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 #ifdef HKS_CONFIG_FILE
17 #include HKS_CONFIG_FILE
18 #else
19 #include "hks_config.h"
20 #endif
21 
22 #include "hks_teec.h"
23 
24 #include <unistd.h>
25 
26 #include "hks_log.h"
27 #include "hks_mem.h"
28 #include "hks_template.h"
29 #include "tee_client_api.h"
30 #include "tee_client_id.h"
31 #include "tee_client_type.h"
32 
33 #ifdef HKS_ROUTER
34 #define HISI_HKS_TA_PATH "/lib/sec/86310d18-5659-47c9-b212-841a3ca4f814.sec"
35 #else
36 #define HISI_HKS_TA_PATH "/vendor/bin/86310d18-5659-47c9-b212-841a3ca4f814.sec"
37 #endif
38 
39 #define MAX_TEE_PARAMS_NUMS 4
40 #define PROVISION_PARAM_COUNT 4
41 
42 #define TEE_SERVICE_HKS_TA \
43 { \
44     0x86310d18, \
45     0x5659, \
46     0x47c9, \
47     { \
48         0xb2, 0x12, 0x84, 0x1a, 0x3c, 0xa4, 0xf8, 0x14 \
49     } \
50 }
51 
52 typedef struct {
53     enum TEEC_ParamType paramType;
54     uint32_t index;
55     union {
56         TEEC_TempMemoryReference tmpRef;
57         TEEC_Value value;
58     };
59 } TeecOpParam;
60 
61 typedef struct {
62     TeecOpParam *params;
63     uint32_t length;
64 } TeecOpParamSet;
65 
66 typedef struct {
67     uint32_t paramTypes;
68     TeecOpParamSet paramSet;
69 } TeecOperation;
70 
71 static TEEC_Context *g_context = NULL;
72 static TEEC_Session *g_sessionSelfStart = NULL;
73 
InitializeBlob(struct HksBlob * blob,uint32_t size,uint8_t * data)74 static inline void InitializeBlob(struct HksBlob *blob, uint32_t size, uint8_t *data)
75 {
76     if (blob != NULL) {
77         blob->data = data;
78         blob->size = size;
79     }
80 }
81 
Uint32To64(uint32_t high,uint32_t low)82 static inline uint64_t Uint32To64(uint32_t high, uint32_t low)
83 {
84     return ((uint64_t)(high) << 32) + (uint64_t)(low); /* 32 is higher bits */
85 }
86 
TeecUuidInit(TEEC_Context * context,const char * taPath,TEEC_UUID * uuid,const char * taName,uint32_t srcLen)87 static TEEC_Result TeecUuidInit(TEEC_Context *context, const char *taPath,
88     TEEC_UUID *uuid, const char *taName, uint32_t srcLen)
89 {
90     if (!access(taPath, F_OK)) {
91         context->ta_path = (uint8_t *)taPath;
92         if (memcpy_s(uuid, sizeof(TEEC_UUID), taName, srcLen) != EOK) {
93             HKS_LOG_E("memcpy failed while copy ta name");
94             return TEEC_ERROR_GENERIC;
95         }
96 
97         return TEEC_SUCCESS;
98     }
99 
100     return TEEC_ERROR_GENERIC;
101 }
102 
OpenSession(TEEC_Context * context,TEEC_Session ** session)103 static TEEC_Result OpenSession(TEEC_Context *context, TEEC_Session **session)
104 {
105     TEEC_UUID uuid = { 0, 0, 0, { 0 } };
106     TEEC_UUID uuidHisi = TEE_SERVICE_HKS_TA;
107     TEEC_Result ret = TeecUuidInit(context, HISI_HKS_TA_PATH, &uuid, (const char*)&uuidHisi, sizeof(TEEC_UUID));
108     if (ret != TEEC_SUCCESS) {
109         HKS_LOG_E("ta uuid init failed!");
110         return TEEC_ERROR_GENERIC;
111     }
112 
113     TEEC_Session *localSession = (TEEC_Session *)HksMalloc(sizeof(TEEC_Session));
114     HKS_IF_NULL_LOGE_RETURN(localSession, (TEEC_Result)TEEC_ERROR_OUT_OF_MEMORY, "out of memory!")
115 
116     TEEC_Operation operation;
117 
118     (void)memset_s(&operation, sizeof(operation), 0, sizeof(operation));
119     operation.started = 1;
120     operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE,
121         TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT);
122 
123     uint32_t origin = 0;
124     ret = TEEC_OpenSession(context, localSession, &uuid, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin);
125     if (ret != TEEC_SUCCESS) {
126         HKS_FREE(localSession);
127         HKS_LOG_E("open ta session failed, ret=0x%" LOG_PUBLIC "x, origin=%" LOG_PUBLIC "u", ret, origin);
128         return ret;
129     }
130 
131     *session = localSession;
132     HKS_LOG_I("Open Session success");
133     return ret;
134 }
135 
TeecOpen(void)136 static TEEC_Result TeecOpen(void)
137 {
138     if (g_context != NULL) {
139         return TEEC_SUCCESS;
140     }
141 
142     g_context = HksMalloc(sizeof(TEEC_Context));
143     HKS_IF_NULL_LOGE_RETURN(g_context, TEEC_ERROR_OUT_OF_MEMORY, "memory allocate failed!")
144 
145     TEEC_Result result = TEEC_InitializeContext(NULL, g_context);
146     if (result != TEEC_SUCCESS) {
147         HKS_LOG_E("Initialize TEE context failed, ret=0x%" LOG_PUBLIC "x", result);
148         HKS_FREE(g_context);
149         return result;
150     }
151 
152     result = OpenSession(g_context, &g_sessionSelfStart);
153     if (result != TEEC_SUCCESS) {
154         TEEC_FinalizeContext(g_context);
155         HKS_FREE(g_context);
156         HKS_LOG_E("Open Session failed!");
157     }
158 
159     return result;
160 }
161 
FillUpCommand(const TeecOpParam * src,TEEC_Parameter * des)162 static void FillUpCommand(const TeecOpParam *src, TEEC_Parameter *des)
163 {
164     switch (src->paramType) {
165         case TEEC_MEMREF_TEMP_INPUT:
166         case TEEC_MEMREF_TEMP_OUTPUT:
167         case TEEC_MEMREF_TEMP_INOUT:
168             des->tmpref.buffer = src->tmpRef.buffer;
169             des->tmpref.size = src->tmpRef.size;
170             break;
171         case TEEC_VALUE_INPUT:
172         case TEEC_VALUE_OUTPUT:
173         case TEEC_VALUE_INOUT:
174             des->value.a = src->value.a;
175             des->value.b = src->value.b;
176             break;
177         case TEEC_NONE:
178             break;
179         default:
180             break;
181     }
182 }
183 
TeecRequestCmdInner(enum HksCmdId pkiCmdId,TEEC_Operation * operation,TeecOperation * teecOperation)184 static TEEC_Result TeecRequestCmdInner(enum HksCmdId pkiCmdId, TEEC_Operation *operation,
185     TeecOperation *teecOperation)
186 {
187     TEEC_Result ret;
188     if (g_sessionSelfStart == NULL) {
189         ret = TeecOpen();
190         if (ret != TEEC_SUCCESS) {
191             HKS_LOG_E("teec open failed!");
192             return ret;
193         }
194     }
195 
196     if (memset_s(operation, sizeof(TEEC_Operation), 0, sizeof(TEEC_Operation)) != EOK) {
197         HKS_LOG_E("memset for operation failed!");
198         return TEEC_ERROR_GENERIC;
199     }
200 
201     operation->started = 1;
202     operation->paramTypes = teecOperation->paramTypes;
203 
204     TeecOpParamSet paramSet = teecOperation->paramSet;
205     TeecOpParam *params = paramSet.params;
206     for (uint32_t i = 0; i < paramSet.length; i++) {
207         FillUpCommand(&params[i], &operation->params[params[i].index]);
208     }
209 
210     uint32_t retOrigin = 0;
211     ret = TEEC_InvokeCommand(g_sessionSelfStart, pkiCmdId, operation, &retOrigin);
212     if (ret != TEEC_SUCCESS) {
213         HKS_LOG_E("invoke km command failed, cmd = %" LOG_PUBLIC "u, ret = 0x%" LOG_PUBLIC "x, "
214             "retOrigin = %" LOG_PUBLIC "u", pkiCmdId, ret, retOrigin);
215     }
216 
217     return ret;
218 }
219 
FillUpArgs(const struct HksParam * src,TeecOpParam * dest)220 static void FillUpArgs(const struct HksParam *src, TeecOpParam *dest)
221 {
222     switch (dest->paramType) {
223         case TEEC_MEMREF_TEMP_INPUT:
224         case TEEC_MEMREF_TEMP_OUTPUT:
225         case TEEC_MEMREF_TEMP_INOUT:
226             dest->tmpRef.buffer = src->blob.data;
227             dest->tmpRef.size = src->blob.size;
228             break;
229         case TEEC_VALUE_INPUT:
230         case TEEC_VALUE_OUTPUT:
231         case TEEC_VALUE_INOUT:
232             dest->value.a = (uint32_t)((src->uint64Param) >> 32); /* 32 is higher bits */
233             dest->value.b = (uint32_t)(src->uint64Param);
234             break;
235         case TEEC_NONE:
236             break;
237         default:
238             break;
239     }
240 }
241 
HksTeeCommand(uint32_t paramTypes,const struct HksParam params[MAX_TEE_PARAMS_NUMS],uint32_t msgType,TEEC_Operation * operation)242 static int32_t HksTeeCommand(uint32_t paramTypes, const struct HksParam params[MAX_TEE_PARAMS_NUMS],
243     uint32_t msgType, TEEC_Operation *operation)
244 {
245     TeecOpParam opParams[MAX_TEE_PARAMS_NUMS];
246     for (uint32_t i = 0; i < MAX_TEE_PARAMS_NUMS; ++i) {
247         opParams[i].index = i;
248         opParams[i].paramType = TEEC_PARAM_TYPE_GET(paramTypes, i);
249         FillUpArgs(&params[i], &opParams[i]);
250     }
251 
252     TeecOpParamSet teeParams = {
253         .params = opParams,
254         .length = MAX_TEE_PARAMS_NUMS
255     };
256     TeecOperation teecOperation = {
257         .paramTypes = paramTypes,
258         .paramSet = teeParams
259     };
260 
261     return TeecRequestCmdInner(msgType, operation, &teecOperation);
262 }
263 
HksTeeOpen(void)264 int32_t HksTeeOpen(void)
265 {
266     return TeecOpen();
267 }
268 
269 #ifdef HKS_SUPPORT_API_INJECT_KEY
HksTeeProvision(const struct HksBlob * keybox,struct HksBlob * challenge,const struct HksBlob * challengeIn,struct HksBlob * signature,struct HksBlob * certData)270 int32_t HksTeeProvision(const struct HksBlob *keybox, struct HksBlob *challenge,
271     const struct HksBlob *challengeIn, struct HksBlob *signature, struct HksBlob *certData)
272 {
273     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_MEMREF_TEMP_INOUT,
274         TEEC_MEMREF_TEMP_OUTPUT, TEEC_MEMREF_TEMP_OUTPUT);
275     struct HksParam params[MAX_TEE_PARAMS_NUMS];
276     InitializeBlob(&params[0].blob, keybox->size, keybox->data);
277     InitializeBlob(&params[1].blob, challenge->size, challenge->data);
278     InitializeBlob(&params[2].blob, signature->size, signature->data); /* 2 is array index */
279     InitializeBlob(&params[3].blob, certData->size, certData->data); /* 3 is array index */
280 
281     TEEC_Operation operation;
282     int32_t ret = HksTeeCommand(paramTypes, params, HKS_CMD_ID_INJECT_KEY, &operation);
283     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "command key provision failed")
284 
285     ret = ProvisionVerify(&operation, challengeIn, (PROVISION_PARAM_COUNT >> 1), NULL, false);
286     HKS_IF_NOT_SUCC_LOGE(ret, "command HksTeeVerifyKeybox failed\n")
287 
288     return ret;
289 }
290 #endif
291 
292 #ifdef HKS_SUPPORT_API_INJECT_KEY_VERIFY
HksTeeProvisionVerify(const struct HksBlob * verify,struct HksBlob * challenge,const struct HksBlob * challengeIn,struct HksBlob * signature)293 int32_t HksTeeProvisionVerify(const struct HksBlob *verify, struct HksBlob *challenge,
294     const struct HksBlob *challengeIn, struct HksBlob *signature)
295 {
296     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_MEMREF_TEMP_INOUT,
297         TEEC_NONE, TEEC_NONE);
298     struct HksParam params[MAX_TEE_PARAMS_NUMS];
299     InitializeBlob(&params[0].blob, signature->size, signature->data);
300     InitializeBlob(&params[1].blob, challenge->size, challenge->data);
301 
302     TEEC_Operation operation;
303     int32_t ret = HksTeeCommand(paramTypes, params, HKS_CMD_ID_INJECT_KEY_VERIFY, &operation);
304     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "command key provision verify failed")
305 
306     /* here we only have one key signature to verify, so the count is half of the provision param count */
307     ret = ProvisionVerify(&operation, challengeIn, (PROVISION_PARAM_COUNT >> 1), verify, true);
308     HKS_IF_NOT_SUCC_LOGE(ret, "verify provision failed")
309 
310     return ret;
311 }
312 #endif
313 
HksTeeGenerateKey(const struct HksBlob * keyBlob,const struct HksParamSet * paramSetIn,struct HksBlob * keyOut)314 int32_t HksTeeGenerateKey(const struct HksBlob *keyBlob, const struct HksParamSet *paramSetIn, struct HksBlob *keyOut)
315 {
316     uint8_t keyInBuffer[MAX_KEY_SIZE] = {0};
317     struct HksBlob keyInBlob = { MAX_KEY_SIZE, keyInBuffer };
318     const struct HksBlob *keyIn = &keyInBlob;
319     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT,
320         TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_OUTPUT);
321     struct HksParam params[MAX_TEE_PARAMS_NUMS];
322     InitializeBlob(&params[0].blob, keyBlob->size, keyBlob->data);
323     InitializeBlob(&params[1].blob, paramSetIn->paramSetSize, (uint8_t *)paramSetIn);
324     InitializeBlob(&params[2].blob, keyIn->size, keyIn->data); /* 2 is array index */
325     InitializeBlob(&params[3].blob, keyOut->size, keyOut->data); /* 3 is array index */
326 
327     TEEC_Operation operation;
328     int32_t ret = HksTeeCommand(paramTypes, params, HKS_CMD_ID_GENERATE_KEY, &operation);
329     if (ret == HKS_SUCCESS) {
330         keyOut->size = operation.params[3].tmpref.size; /* 3 is array index */
331     }
332 
333     return ret;
334 }
335 
HksTeeCheckKeyLegality(const struct HksParamSet * paramSet,const struct HksBlob * key)336 int32_t HksTeeCheckKeyLegality(const struct HksParamSet *paramSet, const struct HksBlob *key)
337 {
338     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE);
339     struct HksParam params[MAX_TEE_PARAMS_NUMS];
340     InitializeBlob(&params[0].blob, paramSet->paramSetSize, (uint8_t *)paramSet);
341     InitializeBlob(&params[1].blob, key->size, key->data);
342 
343     TEEC_Operation operation;
344     int32_t ret = HksTeeCommand(paramTypes, params, HKS_CMD_ID_CHECK_KEY_LEGALITY, &operation);
345     HKS_IF_NOT_SUCC_LOGE(ret, "command HksTeeCheckKeyLegality failed")
346 
347     return ret;
348 }
349 
HksTeeGenerateRandom(const struct HksParamSet * paramSet,struct HksBlob * random)350 int32_t HksTeeGenerateRandom(const struct HksParamSet *paramSet, struct HksBlob *random)
351 {
352     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE);
353     struct HksParam params[MAX_TEE_PARAMS_NUMS];
354     InitializeBlob(&params[0].blob, paramSet->paramSetSize, (uint8_t *)paramSet);
355     InitializeBlob(&params[1].blob, random->size, random->data);
356 
357     TEEC_Operation operation;
358     int32_t ret = HksTeeCommand(paramTypes, params, HKS_CMD_ID_GENERATE_RANDOM, &operation);
359     HKS_IF_NOT_SUCC_LOGE(ret, "command HksTeeGenerateRandom failed")
360 
361     return ret;
362 }
363 
HksTeeImportKey(const struct HksBlob * key,const struct HksParamSet * paramSet,struct HksBlob * keyOut)364 int32_t HksTeeImportKey(const struct HksBlob *key, const struct HksParamSet *paramSet, struct HksBlob *keyOut)
365 {
366     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT,
367         TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE);
368     struct HksParam params[MAX_TEE_PARAMS_NUMS];
369     InitializeBlob(&params[0].blob, key->size, key->data);
370     InitializeBlob(&params[1].blob, paramSet->paramSetSize, (uint8_t *)paramSet);
371     InitializeBlob(&params[2].blob, keyOut->size, keyOut->data); /* 2 is array index */
372 
373     TEEC_Operation operation;
374     int32_t ret = HksTeeCommand(paramTypes, params, HKS_CMD_ID_IMPORT_KEY, &operation);
375     if (ret == HKS_SUCCESS) {
376         keyOut->size = operation.params[2].tmpref.size; /* 2 is array index */
377     }
378 
379     return ret;
380 }
381 
HksTeeExportPublicKey(const struct HksBlob * key,const struct HksParamSet * paramSet,struct HksBlob * keyOut)382 int32_t HksTeeExportPublicKey(const struct HksBlob *key, const struct HksParamSet *paramSet,
383     struct HksBlob *keyOut)
384 {
385     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT,
386         TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE);
387     struct HksParam params[MAX_TEE_PARAMS_NUMS];
388     InitializeBlob(&params[0].blob, key->size, key->data);
389     InitializeBlob(&params[1].blob, paramSet->paramSetSize, (uint8_t *)paramSet);
390     InitializeBlob(&params[2].blob, keyOut->size, keyOut->data); /* 2 is array index */
391 
392     TEEC_Operation operation;
393     int32_t ret = HksTeeCommand(paramTypes, params, HKS_CMD_ID_EXPORT_KEY, &operation);
394     if (ret == HKS_SUCCESS) {
395         keyOut->size = operation.params[2].tmpref.size; /* 2 is array index */
396     }
397 
398     return ret;
399 }
400 
HksTeeAgreeKey(const struct HksParamSet * paramSet,const struct HksBlob * privateKey,const struct HksBlob * peerPublicKey,struct HksBlob * agreedKey)401 int32_t HksTeeAgreeKey(const struct HksParamSet *paramSet, const struct HksBlob *privateKey,
402     const struct HksBlob *peerPublicKey, struct HksBlob *agreedKey)
403 {
404     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT,
405         TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_OUTPUT);
406     struct HksParam params[MAX_TEE_PARAMS_NUMS];
407     InitializeBlob(&params[0].blob, paramSet->paramSetSize, (uint8_t *)paramSet);
408     InitializeBlob(&params[1].blob, privateKey->size, privateKey->data);
409     InitializeBlob(&params[2].blob, peerPublicKey->size, peerPublicKey->data); /* 2 is array index */
410     InitializeBlob(&params[3].blob, agreedKey->size, agreedKey->data); /* 3 is array index */
411 
412     TEEC_Operation operation;
413     int32_t ret = HksTeeCommand(paramTypes, params, HKS_CMD_ID_AGREE_KEY, &operation);
414     if (ret == HKS_SUCCESS) {
415         agreedKey->size = operation.params[3].tmpref.size; /* 3 is array index */
416     }
417 
418     return ret;
419 }
420 
HksTeeDeriveKey(const struct HksParamSet * paramSet,const struct HksBlob * kdfKey,struct HksBlob * derivedKey)421 int32_t HksTeeDeriveKey(const struct HksParamSet *paramSet, const struct HksBlob *kdfKey, struct HksBlob *derivedKey)
422 {
423     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT,
424         TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE);
425     struct HksParam params[MAX_TEE_PARAMS_NUMS];
426     InitializeBlob(&params[0].blob, paramSet->paramSetSize, (uint8_t *)paramSet);
427     InitializeBlob(&params[1].blob, kdfKey->size, kdfKey->data);
428     InitializeBlob(&params[2].blob, derivedKey->size, derivedKey->data); /* 2 is array index */
429 
430     TEEC_Operation operation;
431     int32_t ret = HksTeeCommand(paramTypes, params, HKS_CMD_ID_DERIVE_KEY, &operation);
432     if (ret == HKS_SUCCESS) {
433         derivedKey->size = operation.params[2].tmpref.size; /* 2 is array index */
434     }
435 
436     return ret;
437 }
438 
HksTeeAttestKey(const struct HksBlob * key,const struct HksParamSet * paramSet,struct HksBlob * certChain)439 int32_t HksTeeAttestKey(const struct HksBlob *key, const struct HksParamSet *paramSet,
440     struct HksBlob *certChain)
441 {
442     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT,
443         TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE);
444     struct HksParam params[MAX_TEE_PARAMS_NUMS];
445     InitializeBlob(&params[0].blob, key->size, key->data);
446     InitializeBlob(&params[1].blob, paramSet->paramSetSize, (uint8_t *)paramSet);
447     InitializeBlob(&params[2].blob, certChain->size, certChain->data); /* 2 is array index */
448 
449     TEEC_Operation operation;
450     int32_t ret = HksTeeCommand(paramTypes, params, HKS_CMD_ID_ATTEST_KEY, &operation);
451     if (ret == HKS_SUCCESS) {
452         certChain->size = operation.params[2].tmpref.size; /* 2 is array index */
453     }
454 
455     return ret;
456 }
457 
IsVerify(uint32_t cmdId)458 static bool IsVerify(uint32_t cmdId)
459 {
460     return (cmdId == HKS_CMD_ID_VERIFY || cmdId == HKS_CMD_ID_VERIFY_FINAL);
461 }
462 
ProcessInit(uint32_t cmdId,const struct HksBlob * keyBlob,const struct HksParamSet * paramSet,uint64_t * operationHandle)463 int32_t ProcessInit(uint32_t cmdId, const struct HksBlob *keyBlob, const struct HksParamSet *paramSet,
464     uint64_t *operationHandle)
465 {
466     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT,
467         TEEC_VALUE_OUTPUT, TEEC_NONE);
468     struct HksParam params[MAX_TEE_PARAMS_NUMS];
469     InitializeBlob(&params[0].blob, keyBlob->size, keyBlob->data);
470     InitializeBlob(&params[1].blob, paramSet->paramSetSize, (uint8_t *)paramSet);
471     params[2].uint64Param = 0; /* 2 is array index */
472 
473     TEEC_Operation operation;
474     int32_t ret = HksTeeCommand(paramTypes, params, cmdId, &operation);
475     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "ProcessInit[%" LOG_PUBLIC "u] failed", cmdId)
476 
477     *operationHandle = Uint32To64(operation.params[2].value.a, operation.params[2].value.b); /* 2 is array index */
478     return ret;
479 }
480 
ProcessUpdate(uint32_t cmdId,uint64_t operationHandle,const struct HksBlob * inData,const struct HksBlob * outData,bool isOutput)481 int32_t ProcessUpdate(uint32_t cmdId, uint64_t operationHandle,
482     const struct HksBlob *inData, const struct HksBlob *outData, bool isOutput)
483 {
484     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT,
485         (isOutput ? TEEC_MEMREF_TEMP_OUTPUT : TEEC_NONE), TEEC_NONE);
486     struct HksParam params[MAX_TEE_PARAMS_NUMS];
487     params[0].uint64Param = operationHandle;
488     InitializeBlob(&params[1].blob, inData->size, inData->data);
489 
490     if (isOutput) {
491         InitializeBlob(&params[2].blob, outData->size, outData->data); /* 2 is array index */
492     } else {
493         InitializeBlob(&params[2].blob, 0, NULL); /* 2 is array index */
494     }
495 
496     TEEC_Operation operation;
497     int32_t ret = HksTeeCommand(paramTypes, params, cmdId, &operation);
498     HKS_IF_NOT_SUCC_LOGE(ret, "ProcessUpdate[%" LOG_PUBLIC "u] failed", cmdId)
499 
500     return ret;
501 }
502 
ProcessFinal(uint32_t cmdId,uint64_t operationHandle,const struct HksBlob * srcData,struct HksBlob * inOut,bool isInput)503 int32_t ProcessFinal(uint32_t cmdId, uint64_t operationHandle,
504     const struct HksBlob *srcData, struct HksBlob *inOut, bool isInput)
505 {
506     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_INPUT,
507         isInput ? TEEC_MEMREF_TEMP_INPUT : TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE);
508     struct HksParam params[MAX_TEE_PARAMS_NUMS];
509     params[0].uint64Param = operationHandle;
510     InitializeBlob(&params[1].blob, srcData->size, srcData->data);
511     InitializeBlob(&params[2].blob, inOut->size, inOut->data); /* 2 is array index */
512 
513     TEEC_Operation operation;
514     int32_t ret = HksTeeCommand(paramTypes, params, cmdId, &operation);
515     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "ProcessFinal[%" LOG_PUBLIC "u] failed", cmdId)
516 
517     if (!isInput) {
518         inOut->size = operation.params[2].tmpref.size; /* 2 is array index */
519     }
520     return ret;
521 }
522 
ProcessOnce(uint32_t cmdId,const struct HksBlob * keyBlob,const struct HksParamSet * paramSet,const struct HksBlob * srcData,struct HksBlob * inOut)523 int32_t ProcessOnce(uint32_t cmdId, const struct HksBlob *keyBlob, const struct HksParamSet *paramSet,
524     const struct HksBlob *srcData, struct HksBlob *inOut)
525 {
526     bool isInput = IsVerify(cmdId);
527     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT,
528         isInput ? TEEC_MEMREF_TEMP_INPUT : TEEC_MEMREF_TEMP_OUTPUT);
529 
530     struct HksParam params[MAX_TEE_PARAMS_NUMS];
531     InitializeBlob(&params[0].blob, keyBlob->size, keyBlob->data);
532     InitializeBlob(&params[1].blob, paramSet->paramSetSize, (uint8_t *)paramSet);
533     InitializeBlob(&params[2].blob, srcData->size, srcData->data); /* 2 is array index */
534     InitializeBlob(&params[3].blob, inOut->size, inOut->data); /* 3 is array index */
535 
536     TEEC_Operation operation;
537     int32_t ret = HksTeeCommand(paramTypes, params, cmdId, &operation);
538     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "ProcessOnce[%" LOG_PUBLIC "u] failed", cmdId)
539 
540     if (!isInput) {
541         inOut->size = operation.params[3].tmpref.size; /* 3 is array index */
542     }
543 
544     return ret;
545 }
546 
HksTeeProcessInit(uint32_t cmdId,const struct HksBlob * key,const struct HksParamSet * paramSet,uint64_t * operationHandle)547 int32_t HksTeeProcessInit(uint32_t cmdId, const struct HksBlob *key, const struct HksParamSet *paramSet,
548     uint64_t *operationHandle)
549 {
550     return ProcessInit(cmdId, key, paramSet, operationHandle);
551 }
552 
HksTeeProcessMultiUpdate(uint32_t cmdId,uint64_t operationHandle,const struct HksBlob * inData,struct HksBlob * outData)553 int32_t HksTeeProcessMultiUpdate(uint32_t cmdId, uint64_t operationHandle, const struct HksBlob *inData,
554     struct HksBlob *outData)
555 {
556     bool isOutput = (cmdId == HKS_CMD_ID_ENCRYPT_UPDATE) || (cmdId == HKS_CMD_ID_DECRYPT_UPDATE);
557     return ProcessUpdate(cmdId, operationHandle, inData, outData, isOutput);
558 }
559 
HksTeeSign(const struct HksBlob * keyBlob,const struct HksParamSet * paramSet,const struct HksBlob * srcData,struct HksBlob * signature)560 int32_t HksTeeSign(const struct HksBlob *keyBlob, const struct HksParamSet *paramSet,
561     const struct HksBlob *srcData, struct HksBlob *signature)
562 {
563     return ProcessOnce(HKS_CMD_ID_SIGN, keyBlob, paramSet, srcData, signature);
564 }
565 
HksTeeVerify(const struct HksBlob * keyBlob,const struct HksParamSet * paramSet,const struct HksBlob * srcData,const struct HksBlob * signature)566 int32_t HksTeeVerify(const struct HksBlob *keyBlob, const struct HksParamSet *paramSet,
567     const struct HksBlob *srcData, const struct HksBlob *signature)
568 {
569     return ProcessOnce(HKS_CMD_ID_VERIFY, keyBlob, paramSet, srcData, (struct HksBlob *)signature);
570 }
571 
HksTeeMac(const struct HksBlob * keyBlob,const struct HksParamSet * paramSet,const struct HksBlob * srcData,struct HksBlob * mac)572 int32_t HksTeeMac(const struct HksBlob *keyBlob, const struct HksParamSet *paramSet,
573     const struct HksBlob *srcData, struct HksBlob *mac)
574 {
575     return ProcessOnce(HKS_CMD_ID_MAC, keyBlob, paramSet, srcData, mac);
576 }
577 
HksTeeEncrypt(const struct HksBlob * keyBlob,const struct HksParamSet * paramSet,const struct HksBlob * plainText,struct HksBlob * cipherText)578 int32_t HksTeeEncrypt(const struct HksBlob *keyBlob, const struct HksParamSet *paramSet,
579     const struct HksBlob *plainText, struct HksBlob *cipherText)
580 {
581     return ProcessOnce(HKS_CMD_ID_ENCRYPT, keyBlob, paramSet, plainText, cipherText);
582 }
583 
HksTeeDecrypt(const struct HksBlob * keyBlob,const struct HksParamSet * paramSet,const struct HksBlob * cipherText,struct HksBlob * plainText)584 int32_t HksTeeDecrypt(const struct HksBlob *keyBlob, const struct HksParamSet *paramSet,
585     const struct HksBlob *cipherText, struct HksBlob *plainText)
586 {
587     return ProcessOnce(HKS_CMD_ID_DECRYPT, keyBlob, paramSet, cipherText, plainText);
588 }
589 
HksTeeExportTrustCerts(struct HksBlob * certChain)590 int32_t HksTeeExportTrustCerts(struct HksBlob *certChain)
591 {
592     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
593     struct HksParam params[MAX_TEE_PARAMS_NUMS];
594     InitializeBlob(&params[0].blob, certChain->size, certChain->data);
595 
596     TEEC_Operation operation;
597     int32_t ret = HksTeeCommand(paramTypes, params, HKS_CMD_ID_EXPORT_TRUST_CERT, &operation);
598     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "Invoke HKS_CMD_ID_EXPORT_TRUST_CERT failed")
599 
600     certChain->size = operation.params[0].tmpref.size;
601     return ret;
602 }
603 
HksTeeImportTrustCerts(const struct HksBlob * certChain)604 int32_t HksTeeImportTrustCerts(const struct HksBlob *certChain)
605 {
606     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
607     struct HksParam params[MAX_TEE_PARAMS_NUMS];
608     InitializeBlob(&params[0].blob, certChain->size, certChain->data);
609 
610     TEEC_Operation operation;
611     int32_t ret = HksTeeCommand(paramTypes, params, HKS_CMD_ID_IMPORT_TRUST_CERT, &operation);
612     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "Invoke HKS_CMD_ID_IMPORT_TRUST_CERT failed")
613 
614     return ret;
615 }
616 
HcmTeeIsDeviceKeyExist(void)617 int32_t HcmTeeIsDeviceKeyExist(void)
618 {
619     HKS_LOG_D("enter");
620     uint32_t paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
621     struct HksParam params[MAX_TEE_PARAMS_NUMS] = {0};
622 
623     TEEC_Operation operation;
624     int32_t ret = HksTeeCommand(paramTypes, params, HCM_CMD_ID_IS_DEVICE_KEY_EXIST, &operation);
625     HKS_IF_NOT_SUCC_LOGE(ret, "Invoke HCM_CMD_ID_IS_DEVICE_KEY_EXIST failed")
626 
627     return ret;
628 }
629