1 /*
2  * Copyright (C) 2023 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 "expand_sub_session.h"
17 
18 #include "alg_loader.h"
19 #include "base_cmd.h"
20 #include "device_auth_defines.h"
21 #include "hc_log.h"
22 #include "hc_vector.h"
23 #include "json_utils.h"
24 
25 #include "auth_code_import.h"
26 #include "mk_agree.h"
27 #include "pub_key_exchange.h"
28 #include "save_trusted_info.h"
29 #include "device_auth.h"
30 
31 #define TAG_LEN 16
32 
33 #define EXPAND_SUB_SESSION_AAD "expand_sub_session_add"
34 #define EXPAND_SUB_SESSION_AAD_LEN 22
35 
36 #define CRYPTO_ALG_AES_GCM_256 "AES_GCM_256"
37 
38 #define FIELD_ENC_DATA "encData"
39 #define FIELD_ID "id"
40 #define FIELD_DATA "data"
41 
42 DECLARE_HC_VECTOR(CmdList, BaseCmd *)
43 IMPLEMENT_HC_VECTOR(CmdList, BaseCmd *, 1)
44 
45 typedef BaseCmd *(*CreateCmdFunc)(const void *params, bool isCaller, int32_t strategy);
46 
47 typedef struct {
48     int32_t type;
49     CreateCmdFunc createCmdFunc;
50 } CmdComponent;
51 
52 typedef struct {
53     ExpandSubSession base;
54     Uint8Buff nonce;
55     Uint8Buff encKey;
56     CmdList cmdList;
57 } ExpandSubSessionImpl;
58 
59 static const CmdComponent CMD_COMPONENT_LIB[] = {
60 #ifdef ENABLE_AUTH_CODE_IMPORT
61     {
62         AUTH_CODE_IMPORT_CMD_TYPE,
63         CreateAuthCodeImportCmd,
64     },
65 #endif
66 #ifdef ENABLE_PUB_KEY_EXCHANGE
67     {
68         PUB_KEY_EXCHANGE_CMD_TYPE,
69         CreatePubKeyExchangeCmd,
70     },
71 #endif
72 #ifdef ENABLE_SAVE_TRUSTED_INFO
73     {
74         SAVE_TRUSTED_INFO_CMD_TYPE,
75         CreateSaveTrustedInfoCmd,
76     },
77 #endif
78 #ifdef ENABLE_PSEUDONYM
79     {
80         MK_AGREE_CMD_TYPE,
81         CreateMkAgreeCmd,
82     }
83 #endif
84 };
85 
GetCmdComponent(int32_t type)86 static const CmdComponent *GetCmdComponent(int32_t type)
87 {
88     for (uint32_t i = 0; i < sizeof(CMD_COMPONENT_LIB) / sizeof(CMD_COMPONENT_LIB[0]); i++) {
89         if (CMD_COMPONENT_LIB[i].type == type) {
90             return &CMD_COMPONENT_LIB[i];
91         }
92     }
93     return NULL;
94 }
95 
EncryptMsg(ExpandSubSessionImpl * impl,Uint8Buff * rawData,Uint8Buff * returnEncData)96 static int32_t EncryptMsg(ExpandSubSessionImpl *impl, Uint8Buff *rawData, Uint8Buff *returnEncData)
97 {
98     uint32_t encDataLen = rawData->length + TAG_LEN;
99     uint8_t *encDataVal = (uint8_t *)HcMalloc(encDataLen, 0);
100     if (encDataVal == NULL) {
101         LOGE("allocate encDataVal memory fail.");
102         return HC_ERR_ALLOC_MEMORY;
103     }
104     Uint8Buff encData = { encDataVal, encDataLen };
105     GcmParam gcmParam = { impl->nonce.val, impl->nonce.length,
106         (uint8_t *)EXPAND_SUB_SESSION_AAD, EXPAND_SUB_SESSION_AAD_LEN };
107     KeyParams keyParams = { { impl->encKey.val, impl->encKey.length, false }, false, DEFAULT_OS_ACCOUNT };
108     int32_t res = GetLoaderInstance()->aesGcmEncrypt(&keyParams, rawData, &gcmParam, &encData);
109     if (res != HC_SUCCESS) {
110         LOGE("aesGcmEncrypt rawData failed.");
111         HcFree(encDataVal);
112         return res;
113     }
114     returnEncData->val = encDataVal;
115     returnEncData->length = encDataLen;
116     return HC_SUCCESS;
117 }
118 
DecryptMsg(ExpandSubSessionImpl * impl,Uint8Buff * encData,Uint8Buff * returnRawData)119 static int32_t DecryptMsg(ExpandSubSessionImpl *impl, Uint8Buff *encData, Uint8Buff *returnRawData)
120 {
121     uint32_t rawDataLen = encData->length - TAG_LEN;
122     uint8_t *rawDataVal = (uint8_t *)HcMalloc(rawDataLen, 0);
123     if (rawDataVal == NULL) {
124         LOGE("allocate rawDataVal memory fail.");
125         return HC_ERR_ALLOC_MEMORY;
126     }
127     Uint8Buff rawData = { rawDataVal, rawDataLen };
128     GcmParam gcmParam = { impl->nonce.val, impl->nonce.length,
129         (uint8_t *)EXPAND_SUB_SESSION_AAD, EXPAND_SUB_SESSION_AAD_LEN };
130     KeyParams keyParams = { { impl->encKey.val, impl->encKey.length, false }, false, DEFAULT_OS_ACCOUNT };
131     int32_t res = GetLoaderInstance()->aesGcmDecrypt(&keyParams, encData, &gcmParam, &rawData);
132     if (res != HC_SUCCESS) {
133         LOGE("aesGcmDecrypt rawData failed.");
134         HcFree(rawDataVal);
135         return res;
136     }
137     returnRawData->val = rawDataVal;
138     returnRawData->length = rawDataLen;
139     return HC_SUCCESS;
140 }
141 
GetRecvEncData(const CJson * receviedMsg,Uint8Buff * recvEncData)142 static int32_t GetRecvEncData(const CJson *receviedMsg, Uint8Buff *recvEncData)
143 {
144     const char *base64Str = GetStringFromJson(receviedMsg, FIELD_ENC_DATA);
145     if (base64Str == NULL) {
146         LOGE("get encData from json failed.");
147         return HC_ERR_JSON_GET;
148     }
149     uint32_t recvEncDataLen = HcStrlen(base64Str) / BYTE_TO_BASE64_MULTIPLIER * BYTE_TO_BASE64_DIVISOR;
150     uint8_t *recvEncDataVal = (uint8_t *)HcMalloc(recvEncDataLen, 0);
151     if (recvEncDataVal == NULL) {
152         LOGE("allocate recvEncDataVal memory fail.");
153         return HC_ERR_ALLOC_MEMORY;
154     }
155     uint32_t outLen = 0;
156     if (GetLoaderInstance()->base64Decode(base64Str, HcStrlen(base64Str),
157         recvEncDataVal, recvEncDataLen, &outLen) != HC_SUCCESS) {
158         LOGE("base64 decode fail.");
159         HcFree(recvEncDataVal);
160         return HC_ERR_CONVERT_FAILED;
161     }
162     recvEncData->val = recvEncDataVal;
163     recvEncData->length = outLen;
164     return HC_SUCCESS;
165 }
166 
GetRecvCmdList(ExpandSubSessionImpl * impl,const CJson * receviedMsg,CJson ** cmdList)167 static int32_t GetRecvCmdList(ExpandSubSessionImpl *impl, const CJson *receviedMsg, CJson **cmdList)
168 {
169     Uint8Buff recvEncData;
170     int32_t res = GetRecvEncData(receviedMsg, &recvEncData);
171     if (res != HC_SUCCESS) {
172         return res;
173     }
174     Uint8Buff recvRawData;
175     res = DecryptMsg(impl, &recvEncData, &recvRawData);
176     FreeUint8Buff(&recvEncData);
177     if (res != HC_SUCCESS) {
178         LOGE("decryptMsg fail.");
179         return res;
180     }
181     CJson *rawRecvJson = CreateJsonFromString((const char *)(recvRawData.val));
182     FreeUint8Buff(&recvRawData);
183     if (rawRecvJson == NULL) {
184         LOGE("create json from recvRawData fail.");
185         return HC_ERR_JSON_CREATE;
186     }
187     *cmdList = rawRecvJson;
188     return HC_SUCCESS;
189 }
190 
AddSendCmdDataToList(int32_t cmdType,const CJson * sendCmdData,CJson * sendCmdList)191 static int32_t AddSendCmdDataToList(int32_t cmdType, const CJson *sendCmdData, CJson *sendCmdList)
192 {
193     CJson *sendCmd = CreateJson();
194     if (sendCmd == NULL) {
195         LOGE("allocate sendCmd memory fail.");
196         return HC_ERR_ALLOC_MEMORY;
197     }
198     if (AddIntToJson(sendCmd, FIELD_ID, cmdType) != HC_SUCCESS) {
199         LOGE("add cmdType to json fail.");
200         FreeJson(sendCmd);
201         return HC_ERR_JSON_ADD;
202     }
203     if (AddObjToJson(sendCmd, FIELD_DATA, sendCmdData) != HC_SUCCESS) {
204         LOGE("add cmdData to json fail.");
205         FreeJson(sendCmd);
206         return HC_ERR_JSON_ADD;
207     }
208     if (AddObjToArray(sendCmdList, sendCmd) != HC_SUCCESS) {
209         LOGE("add cmdData to json fail.");
210         FreeJson(sendCmd);
211         return HC_ERR_JSON_ADD;
212     }
213     return HC_SUCCESS;
214 }
215 
ProcCmd(BaseCmd * cmd,const CJson * recvCmdData,CJson * sendCmdList,bool * isFinish)216 static int32_t ProcCmd(BaseCmd *cmd, const CJson *recvCmdData, CJson *sendCmdList, bool *isFinish)
217 {
218     CmdState cmdState;
219     CJson *sendCmdData = NULL;
220     int32_t res = cmd->process(cmd, recvCmdData, &sendCmdData, &cmdState);
221     if (res != HC_SUCCESS) {
222         if (sendCmdData != NULL) {
223             (void)AddSendCmdDataToList(cmd->type, sendCmdData, sendCmdList);
224             FreeJson(sendCmdData);
225         }
226         return res;
227     }
228     if (sendCmdData != NULL) {
229         res = AddSendCmdDataToList(cmd->type, sendCmdData, sendCmdList);
230         FreeJson(sendCmdData);
231     }
232     *isFinish = (cmdState == CMD_STATE_FINISH);
233     return res;
234 }
235 
ProcRecvCmd(ExpandSubSessionImpl * impl,const CJson * recvCmd,CJson * sendCmdList)236 static int32_t ProcRecvCmd(ExpandSubSessionImpl *impl, const CJson *recvCmd, CJson *sendCmdList)
237 {
238     int32_t cmdType;
239     if (GetIntFromJson(recvCmd, FIELD_ID, &cmdType) != HC_SUCCESS) {
240         LOGE("get cmdType from recvCmd fail.");
241         return HC_ERR_JSON_GET;
242     }
243     CJson *recvCmdData = GetObjFromJson(recvCmd, FIELD_DATA);
244     if (recvCmdData == NULL) {
245         LOGE("get recvCmdData from recvCmd fail.");
246         return HC_ERR_JSON_GET;
247     }
248     uint32_t index;
249     BaseCmd **iter;
250     FOR_EACH_HC_VECTOR(impl->cmdList, index, iter) {
251         BaseCmd *cmd = *iter;
252         if (cmd->type != cmdType) {
253             continue;
254         }
255         bool isFinish = false;
256         int32_t res = ProcCmd(cmd, recvCmdData, sendCmdList, &isFinish);
257         if (res == HC_SUCCESS && !isFinish) {
258             return HC_SUCCESS;
259         }
260         if (res != HC_SUCCESS && cmd->strategy == CONTINUE_IF_ERROR) {
261             res = HC_SUCCESS;
262         }
263         BaseCmd *popCmd = NULL;
264         HC_VECTOR_POPELEMENT(&impl->cmdList, &popCmd, index);
265         popCmd->destroy(popCmd);
266         return res;
267     }
268     LOGE("cmd not found. [Cmd]: %d", cmdType);
269     return HC_ERR_JSON_GET;
270 }
271 
ProcAllRecvCmds(ExpandSubSessionImpl * impl,const CJson * receviedMsg,CJson * sendCmdList)272 static int32_t ProcAllRecvCmds(ExpandSubSessionImpl *impl, const CJson *receviedMsg, CJson *sendCmdList)
273 {
274     CJson *recvCmdList;
275     int32_t res = GetRecvCmdList(impl, receviedMsg, &recvCmdList);
276     if (res != HC_SUCCESS) {
277         return res;
278     }
279     int32_t cmdNum = GetItemNum(recvCmdList);
280     for (int32_t i = 0; i < cmdNum; i++) {
281         res = ProcRecvCmd(impl, GetItemFromArray(recvCmdList, i), sendCmdList);
282         if (res != HC_SUCCESS) {
283             FreeJson(recvCmdList);
284             return res;
285         }
286     }
287     LOGI("proc all recv cmd success. [CmdNum]: %u", cmdNum);
288     FreeJson(recvCmdList);
289     return HC_SUCCESS;
290 }
291 
StartCmd(BaseCmd * cmd,CJson * sendCmdList)292 static int32_t StartCmd(BaseCmd *cmd, CJson *sendCmdList)
293 {
294     CJson *sendCmdData = NULL;
295     int32_t res = cmd->start(cmd, &sendCmdData);
296     if (res != HC_SUCCESS) {
297         LOGE("start cmd error. [Cmd]: %d", cmd->type);
298         if (sendCmdData != NULL) {
299             (void)AddSendCmdDataToList(cmd->type, sendCmdData, sendCmdList);
300             FreeJson(sendCmdData);
301         }
302         return res;
303     }
304     res = AddSendCmdDataToList(cmd->type, sendCmdData, sendCmdList);
305     FreeJson(sendCmdData);
306     return res;
307 }
308 
StartNewCmds(ExpandSubSessionImpl * impl,CJson * sendCmdList)309 static int32_t StartNewCmds(ExpandSubSessionImpl *impl, CJson *sendCmdList)
310 {
311     uint32_t index;
312     BaseCmd **iter;
313     FOR_EACH_HC_VECTOR(impl->cmdList, index, iter) {
314         BaseCmd *cmd = *iter;
315         if ((!cmd->isCaller) || (cmd->curState != cmd->beginState)) {
316             continue;
317         }
318         int32_t res = StartCmd(cmd, sendCmdList);
319         if (res != HC_SUCCESS && cmd->strategy == ABORT_IF_ERROR) {
320             return res;
321         }
322     }
323     return HC_SUCCESS;
324 }
325 
BuildEncData(ExpandSubSessionImpl * impl,CJson * sendCmdList,CJson * sendMsg)326 static int32_t BuildEncData(ExpandSubSessionImpl *impl, CJson *sendCmdList, CJson *sendMsg)
327 {
328     char *rawSendStr = PackJsonToString(sendCmdList);
329     if (rawSendStr == NULL) {
330         LOGE("pack rawSendStr to string fail.");
331         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
332     }
333     Uint8Buff sendEncData = { NULL, 0 };
334     Uint8Buff sendRawData = { (uint8_t *)rawSendStr, HcStrlen(rawSendStr) + 1 };
335     int32_t res = EncryptMsg(impl, &sendRawData, &sendEncData);
336     FreeJsonString(rawSendStr);
337     if (res != HC_SUCCESS) {
338         LOGE("encryptMsg fail.");
339         return res;
340     }
341     uint32_t base64StrLen = (sendEncData.length / BYTE_TO_BASE64_DIVISOR +
342         (sendEncData.length % BYTE_TO_BASE64_DIVISOR != 0)) * BYTE_TO_BASE64_MULTIPLIER + 1;
343     char *base64Str = (char *)HcMalloc(base64StrLen, 0);
344     if (base64Str == NULL) {
345         LOGE("allocate base64Str memory fail.");
346         FreeUint8Buff(&sendEncData);
347         return HC_ERR_ALLOC_MEMORY;
348     }
349     uint32_t outLen = 0;
350     res = GetLoaderInstance()->base64Encode(sendEncData.val, sendEncData.length, base64Str, base64StrLen, &outLen);
351     FreeUint8Buff(&sendEncData);
352     if (res != HC_SUCCESS) {
353         LOGE("base64 encode fail.");
354         HcFree(base64Str);
355         return HC_ERR_CONVERT_FAILED;
356     }
357     if (AddStringToJson(sendMsg, FIELD_ENC_DATA, base64Str) != HC_SUCCESS) {
358         LOGE("add encData to json fail.");
359         HcFree(base64Str);
360         return HC_ERR_JSON_ADD;
361     }
362     HcFree(base64Str);
363     return HC_SUCCESS;
364 }
365 
PackSendMsg(ExpandSubSessionImpl * impl,CJson * sendCmdList,CJson ** returnSendMsg)366 static int32_t PackSendMsg(ExpandSubSessionImpl *impl, CJson *sendCmdList, CJson **returnSendMsg)
367 {
368     CJson *sendMsg = CreateJson();
369     if (sendMsg == NULL) {
370         LOGE("allocate sendMsg memory fail.");
371         return HC_ERR_ALLOC_MEMORY;
372     }
373     int32_t res = BuildEncData(impl, sendCmdList, sendMsg);
374     if (res != HC_SUCCESS) {
375         FreeJson(sendMsg);
376         return res;
377     }
378     *returnSendMsg = sendMsg;
379     LOGI("pack send msg success.");
380     return HC_SUCCESS;
381 }
382 
AddExpandProcess(ExpandSubSession * self,int32_t cmdType,void * params,bool isCaller,int32_t strategy)383 static int32_t AddExpandProcess(ExpandSubSession *self, int32_t cmdType, void *params,
384     bool isCaller, int32_t strategy)
385 {
386     if ((self == NULL) || (params == NULL)) {
387         LOGE("invalid params.");
388         return HC_ERR_NULL_PTR;
389     }
390     ExpandSubSessionImpl *impl = (ExpandSubSessionImpl *)self;
391     if (impl->base.state != EXPAND_STATE_INIT) {
392         LOGE("invalid state. [State]: %d", impl->base.state);
393         return HC_ERR_UNSUPPORTED_OPCODE;
394     }
395     const CmdComponent *component = GetCmdComponent(cmdType);
396     if (component == NULL) {
397         LOGE("no cmd component found. cmdType = %d.", cmdType);
398         return HC_ERR_UNSUPPORTED_OPCODE;
399     }
400     BaseCmd *instance = component->createCmdFunc(params, isCaller, strategy);
401     if (instance == NULL) {
402         LOGE("create cmd instance fail.");
403         return HC_ERR_NULL_PTR;
404     }
405     if (impl->cmdList.pushBackT(&impl->cmdList, instance) == NULL) {
406         LOGE("push cmd to list fail.");
407         instance->destroy(instance);
408         return HC_ERR_ALLOC_MEMORY;
409     }
410     LOGI("add expand process success. [Cmd]: %d, [IsCaller]: %s", cmdType, isCaller ? "Client" : "Server");
411     return HC_SUCCESS;
412 }
413 
StartExpandSubSession(ExpandSubSession * self,CJson ** returnSendMsg)414 static int32_t StartExpandSubSession(ExpandSubSession *self, CJson **returnSendMsg)
415 {
416     if ((self == NULL) || (returnSendMsg == NULL)) {
417         LOGE("invalid params.");
418         return HC_ERR_INVALID_PARAMS;
419     }
420     ExpandSubSessionImpl *impl = (ExpandSubSessionImpl *)self;
421     if (impl->base.state != EXPAND_STATE_INIT) {
422         LOGE("invalid state. [State]: %d", impl->base.state);
423         return HC_ERR_UNSUPPORTED_OPCODE;
424     }
425     if (HC_VECTOR_SIZE(&impl->cmdList) == 0) {
426         LOGE("The list of cmd is empty.");
427         return HC_ERR_UNSUPPORTED_OPCODE;
428     }
429     CJson *sendCmdList = CreateJsonArray();
430     if (sendCmdList == NULL) {
431         LOGE("allocate sendCmdList memory fail.");
432         return HC_ERR_ALLOC_MEMORY;
433     }
434     int32_t res = StartNewCmds(impl, sendCmdList);
435     if (res != HC_SUCCESS) {
436         if (GetItemNum(sendCmdList) > 0) {
437             (void)PackSendMsg(impl, sendCmdList, returnSendMsg);
438         }
439         FreeJson(sendCmdList);
440         return res;
441     }
442     res = PackSendMsg(impl, sendCmdList, returnSendMsg);
443     FreeJson(sendCmdList);
444     if (res == HC_SUCCESS) {
445         impl->base.state = EXPAND_STATE_RUNNING;
446     }
447     return res;
448 }
449 
ProcessExpandSubSession(ExpandSubSession * self,const CJson * receviedMsg,CJson ** returnSendMsg)450 static int32_t ProcessExpandSubSession(ExpandSubSession *self, const CJson *receviedMsg,
451     CJson **returnSendMsg)
452 {
453     if ((self == NULL) || (receviedMsg == NULL) || (returnSendMsg == NULL)) {
454         LOGE("invalid params.");
455         return HC_ERR_INVALID_PARAMS;
456     }
457     ExpandSubSessionImpl *impl = (ExpandSubSessionImpl *)self;
458     if ((impl->base.state != EXPAND_STATE_INIT) && (impl->base.state != EXPAND_STATE_RUNNING)) {
459         LOGE("invalid state. [State]: %d", impl->base.state);
460         return HC_ERR_UNSUPPORTED_OPCODE;
461     }
462     CJson *sendCmdList = CreateJsonArray();
463     if (sendCmdList == NULL) {
464         LOGE("allocate sendCmdList memory fail.");
465         return HC_ERR_ALLOC_MEMORY;
466     }
467     int32_t res;
468     do {
469         res = ProcAllRecvCmds(impl, receviedMsg, sendCmdList);
470         if (res != HC_SUCCESS) {
471             break;
472         }
473         res = StartNewCmds(impl, sendCmdList);
474     } while (0);
475     if (GetItemNum(sendCmdList) > 0) {
476         (void)PackSendMsg(impl, sendCmdList, returnSendMsg);
477     }
478     FreeJson(sendCmdList);
479     if (res == HC_SUCCESS) {
480         impl->base.state = HC_VECTOR_SIZE(&impl->cmdList) > 0 ? EXPAND_STATE_RUNNING : EXPAND_STATE_FINISH;
481     }
482     return res;
483 }
484 
DestroyExpandSubSession(ExpandSubSession * self)485 static void DestroyExpandSubSession(ExpandSubSession *self)
486 {
487     if (self == NULL) {
488         LOGD("self is NULL.");
489         return;
490     }
491     ExpandSubSessionImpl *impl = (ExpandSubSessionImpl *)self;
492     ClearFreeUint8Buff(&(impl->nonce));
493     ClearFreeUint8Buff(&(impl->encKey));
494     uint32_t index;
495     BaseCmd **iter;
496     FOR_EACH_HC_VECTOR(impl->cmdList, index, iter) {
497         (*iter)->destroy(*iter);
498     }
499     DESTROY_HC_VECTOR(CmdList, &impl->cmdList);
500     HcFree(impl);
501 }
502 
CreateExpandSubSession(const Uint8Buff * nonce,const Uint8Buff * encKey,ExpandSubSession ** returnObj)503 int32_t CreateExpandSubSession(const Uint8Buff *nonce, const Uint8Buff *encKey, ExpandSubSession **returnObj)
504 {
505     if ((nonce == NULL) || (nonce->val == NULL)) {
506         LOGE("nonce is NULL");
507         return HC_ERR_INVALID_PARAMS;
508     }
509     if ((encKey == NULL) || (encKey->val == NULL)) {
510         LOGE("encKey is NULL");
511         return HC_ERR_INVALID_PARAMS;
512     }
513     if (returnObj == NULL) {
514         LOGE("returnObj is NULL");
515         return HC_ERR_INVALID_PARAMS;
516     }
517     ExpandSubSessionImpl *impl = (ExpandSubSessionImpl *)HcMalloc(sizeof(ExpandSubSessionImpl), 0);
518     if (impl == NULL) {
519         LOGE("allocate impl memory fail.");
520         return HC_ERR_ALLOC_MEMORY;
521     }
522     if (DeepCopyUint8Buff(nonce, &(impl->nonce)) != HC_SUCCESS) {
523         LOGE("copy nonce fail.");
524         HcFree(impl);
525         return HC_ERR_ALLOC_MEMORY;
526     }
527     if (DeepCopyUint8Buff(encKey, &(impl->encKey)) != HC_SUCCESS) {
528         LOGE("copy encKey fail.");
529         ClearFreeUint8Buff(&impl->nonce);
530         HcFree(impl);
531         return HC_ERR_ALLOC_MEMORY;
532     }
533     impl->base.addCmd = AddExpandProcess;
534     impl->base.start = StartExpandSubSession;
535     impl->base.process = ProcessExpandSubSession;
536     impl->base.destroy = DestroyExpandSubSession;
537     impl->base.state = EXPAND_STATE_INIT;
538     impl->cmdList = CREATE_HC_VECTOR(CmdList);
539     *returnObj = (ExpandSubSession *)impl;
540     return HC_SUCCESS;
541 }
542 
IsCmdSupport(int32_t cmdId)543 bool IsCmdSupport(int32_t cmdId)
544 {
545     return GetCmdComponent(cmdId) != NULL;
546 }
547