1 /*
2 * Copyright (C) 2021 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 "iso_client_unbind_exchange_task.h"
17 #include "hc_log.h"
18 #include "hc_types.h"
19 #include "iso_task_common.h"
20
21 enum {
22 TASK_TYPE_BEGIN = 1,
23 TASK_TYPE_FINAL,
24 };
25
GetTaskType(void)26 static CurTaskType GetTaskType(void)
27 {
28 return TASK_TYPE_UNBIND_LITE_EXCHANGE;
29 }
30
DestroyClientUnbindExchangeTask(struct SymBaseCurTaskT * task)31 static void DestroyClientUnbindExchangeTask(struct SymBaseCurTaskT *task)
32 {
33 HcFree(task);
34 }
35
Process(struct SymBaseCurTaskT * task,IsoParams * params,const CJson * in,CJson * out,int32_t * status)36 static int Process(struct SymBaseCurTaskT *task, IsoParams *params, const CJson *in, CJson *out, int32_t *status)
37 {
38 IsoClientUnbindExchangeTask *realTask = (IsoClientUnbindExchangeTask *)task;
39 if (realTask->taskBase.taskStatus < TASK_TYPE_BEGIN) {
40 LOGE("Invalid taskStatus: %d", realTask->taskBase.taskStatus);
41 return HC_ERR_BAD_MESSAGE;
42 }
43
44 if (realTask->taskBase.taskStatus > TASK_TYPE_BEGIN) {
45 LOGI("The message is repeated, ignore it, status: %d", realTask->taskBase.taskStatus);
46 *status = IGNORE_MSG;
47 return HC_SUCCESS;
48 }
49 int res;
50 uint8_t *keyAlias = NULL;
51 int32_t message = 0;
52 res = GetIntFromJson(in, FIELD_MESSAGE, &message);
53 if (res != 0 || message != ISO_SERVER_UNBIND_EXCHANGE_RET) {
54 return HC_ERR_BAD_MESSAGE;
55 }
56 res = CheckEncResult(params, in, UNBIND_ADD_RESPONSE);
57 if (res != 0) {
58 LOGE("CheckEncResult failed, res:%d", res);
59 return res;
60 }
61 keyAlias = (uint8_t *)HcMalloc(ISO_KEY_ALIAS_LEN, 0);
62 if (keyAlias == NULL) {
63 res = HC_ERR_ALLOC_MEMORY;
64 goto ERR;
65 }
66 res = GenerateKeyAliasInIso(params, keyAlias, ISO_KEY_ALIAS_LEN, true);
67 if (res != 0) {
68 LOGE("GenerateKeyAliasInIso failed, res:%d", res);
69 goto ERR;
70 }
71 LOGI("AuthCode alias: %x%x%x%x****.", keyAlias[0], keyAlias[1], keyAlias[2], keyAlias[3]);
72 Uint8Buff outKeyAlias = { (uint8_t *)keyAlias, ISO_KEY_ALIAS_LEN };
73 res = params->baseParams.loader->deleteKey(&outKeyAlias);
74 if (res != 0) {
75 LOGE("delete auth code failed, res:%d", res);
76 goto ERR;
77 }
78 res = SendResultToFinalSelf(params, out, false);
79 if (res == 0) {
80 realTask->taskBase.taskStatus = TASK_TYPE_FINAL;
81 *status = FINISH;
82 }
83 ERR:
84 HcFree(keyAlias);
85 return res;
86 }
87
PackDataForStartUnbind(const IsoParams * params,const Uint8Buff * encDataBuf,const Uint8Buff * nonceBuf,CJson * out)88 static int PackDataForStartUnbind(const IsoParams *params, const Uint8Buff *encDataBuf, const Uint8Buff *nonceBuf,
89 CJson *out)
90 {
91 int res = 0;
92 CJson *payload = NULL;
93 CJson *sendToPeer = NULL;
94
95 payload = CreateJson();
96 if (payload == NULL) {
97 res = HC_ERR_ALLOC_MEMORY;
98 goto ERR;
99 }
100 sendToPeer = CreateJson();
101 if (sendToPeer == NULL) {
102 res = HC_ERR_ALLOC_MEMORY;
103 goto ERR;
104 }
105 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_MESSAGE, ISO_CLIENT_UNBIND_EXCHANGE_CMD), res);
106 GOTO_ERR_AND_SET_RET(AddIntToJson(payload, FIELD_OPERATION_CODE, params->opCode), res);
107 GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_ENC_DATA, encDataBuf->val, encDataBuf->length), res);
108 GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_NONCE, nonceBuf->val, nonceBuf->length), res);
109 GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_PAYLOAD, payload), res);
110 GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), res);
111 ERR:
112 FreeJson(payload);
113 FreeJson(sendToPeer);
114 return res;
115 }
116
GenerateEncRemoveInfo(const IsoParams * params,const Uint8Buff * nonceBuf,CJson * out)117 static int GenerateEncRemoveInfo(const IsoParams *params, const Uint8Buff *nonceBuf, CJson *out)
118 {
119 int res;
120 char *rmvInfoStr = NULL;
121 uint8_t *encData = NULL;
122 CJson *rmvInfoJson = CreateJson();
123 if (rmvInfoJson == NULL) {
124 LOGE("Create json failed");
125 return HC_ERR_ALLOC_MEMORY;
126 }
127 GOTO_ERR_AND_SET_RET(AddByteToJson(rmvInfoJson, FIELD_RMV_ID, params->baseParams.authIdSelf.val,
128 params->baseParams.authIdSelf.length), res);
129 GOTO_ERR_AND_SET_RET(AddIntToJson(rmvInfoJson, FIELD_RMV_TYPE, params->selfUserType), res);
130 rmvInfoStr = PackJsonToString(rmvInfoJson);
131 if (rmvInfoStr == NULL) {
132 LOGE("rmvInfoStr PackJsonToString failed");
133 res = HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
134 goto ERR;
135 }
136
137 Uint8Buff removeInfoBuf = { (uint8_t *)rmvInfoStr, strlen(rmvInfoStr) };
138
139 int encDataLen = strlen(rmvInfoStr) + TAG_LEN;
140 encData = (uint8_t *)HcMalloc(encDataLen, 0);
141 if (encData == NULL) {
142 res = HC_ERR_ALLOC_MEMORY;
143 goto ERR;
144 }
145 Uint8Buff encDataBuf = { encData, encDataLen };
146 GcmParam gcmParam;
147 gcmParam.aad = (uint8_t *)UNBIND_ADD_REQUEST;
148 gcmParam.aadLen = (uint32_t)strlen(UNBIND_ADD_REQUEST);
149 gcmParam.nonce = nonceBuf->val;
150 gcmParam.nonceLen = nonceBuf->length;
151 res = params->baseParams.loader->aesGcmEncrypt(¶ms->baseParams.sessionKey, &removeInfoBuf, &gcmParam, false,
152 &encDataBuf);
153 if (res != 0) {
154 LOGE("encrypt removeInfo failed, res:%d", res);
155 goto ERR;
156 }
157 res = PackDataForStartUnbind(params, &encDataBuf, nonceBuf, out);
158 if (res != HC_SUCCESS) {
159 LOGE("PackDataForStartUnbind failed, res:%d", res);
160 }
161 ERR:
162 FreeJson(rmvInfoJson);
163 FreeJsonString(rmvInfoStr);
164 HcFree(encData);
165 return res;
166 }
167
168
ClientUnbindExchangeStart(const IsoParams * params,IsoClientUnbindExchangeTask * task,CJson * out,int32_t * status)169 static int ClientUnbindExchangeStart(const IsoParams *params, IsoClientUnbindExchangeTask *task, CJson *out,
170 int32_t *status)
171 {
172 int res;
173 uint8_t *nonce = NULL;
174
175 nonce = (uint8_t *)HcMalloc(NONCE_SIZE, 0);
176 if (nonce == NULL) {
177 res = HC_ERR_ALLOC_MEMORY;
178 goto ERR;
179 }
180 Uint8Buff nonceBuf = { nonce, NONCE_SIZE };
181 res = params->baseParams.loader->generateRandom(&nonceBuf);
182 if (res != 0) {
183 LOGE("generate nonce failed, res:%d", res);
184 goto ERR;
185 }
186
187 res = GenerateEncRemoveInfo(params, &nonceBuf, out);
188 if (res != 0) {
189 LOGE("GenerateEncRemoveInfo failed, res:%d", res);
190 goto ERR;
191 }
192 task->taskBase.taskStatus = TASK_TYPE_BEGIN;
193 *status = CONTINUE;
194 ERR:
195 HcFree(nonce);
196 return res;
197 }
198
CreateClientUnbindExchangeTask(IsoParams * params,const CJson * in,CJson * out,int32_t * status)199 SymBaseCurTask *CreateClientUnbindExchangeTask(IsoParams *params, const CJson *in, CJson *out, int32_t *status)
200 {
201 (void)in;
202 IsoClientUnbindExchangeTask *task = (IsoClientUnbindExchangeTask *)HcMalloc(sizeof(IsoClientUnbindExchangeTask), 0);
203 if (task == NULL) {
204 return NULL;
205 }
206 task->taskBase.destroyTask = DestroyClientUnbindExchangeTask;
207 task->taskBase.process = Process;
208 task->taskBase.getCurTaskType = GetTaskType;
209 int res = ClientUnbindExchangeStart(params, task, out, status);
210 if (res != 0) {
211 DestroyClientUnbindExchangeTask((struct SymBaseCurTaskT *)task);
212 return NULL;
213 }
214 return (SymBaseCurTask *)task;
215 }
216