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_server_protocol_task.h"
17 #include "common_defs.h"
18 #include "das_task_common.h"
19 #include "hc_log.h"
20 #include "hc_types.h"
21 #include "iso_protocol_common.h"
22 #include "iso_task_common.h"
23 #include "protocol_common.h"
24
25 enum {
26 TASK_STATUS_BEGIN = 0,
27 TASK_STATUS_CMD_RES_TOKEN,
28 TASK_STATUS_GEN_SESSION_KEY,
29 TASK_STATUS_FINAL,
30 };
31
GetTaskType(void)32 static CurTaskType GetTaskType(void)
33 {
34 return TASK_TYPE_ISO_PROTOCOL;
35 }
36
DestroyProtocolServerTask(struct SymBaseCurTaskT * task)37 static void DestroyProtocolServerTask(struct SymBaseCurTaskT *task)
38 {
39 HcFree(task);
40 }
41
PackageServerStartMessage(const IsoParams * params,const Uint8Buff * selfTokenBuf,CJson * out)42 static int PackageServerStartMessage(const IsoParams *params, const Uint8Buff *selfTokenBuf, CJson *out)
43 {
44 int res;
45 CJson *payload = NULL;
46 CJson *sendToPeer = NULL;
47 payload = CreateJson();
48 if (payload == NULL) {
49 LOGE("Create payload json failed.");
50 res = HC_ERR_JSON_CREATE;
51 goto ERR;
52 }
53 sendToPeer = CreateJson();
54 if (sendToPeer == NULL) {
55 LOGE("Create sendToPeer json failed.");
56 res = HC_ERR_JSON_CREATE;
57 goto ERR;
58 }
59 GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_ISO_SALT, params->baseParams.randSelf.val,
60 params->baseParams.randSelf.length), res);
61 GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_TOKEN, selfTokenBuf->val, selfTokenBuf->length), res);
62 GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_PEER_AUTH_ID, params->baseParams.authIdSelf.val,
63 params->baseParams.authIdSelf.length), res);
64 GOTO_ERR_AND_SET_RET(AddIntToJson(payload, FIELD_PEER_USER_TYPE, params->selfUserType), res);
65 GOTO_ERR_AND_SET_RET(AddIntToJson(payload, FIELD_OPERATION_CODE, params->opCode), res);
66 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_AUTH_FORM, AUTH_FORM_ACCOUNT_UNRELATED), res);
67 GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_PAYLOAD, payload), res);
68 GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), res);
69 ERR:
70 FreeJson(payload);
71 FreeJson(sendToPeer);
72 return res;
73 }
74
IsoServerStart(SymBaseCurTask * task,IsoParams * params,const CJson * in,CJson * out,int32_t * status)75 static int IsoServerStart(SymBaseCurTask *task, IsoParams *params, const CJson *in, CJson *out, int32_t *status)
76 {
77 if (task->taskStatus != TASK_STATUS_BEGIN) {
78 LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
79 *status = IGNORE_MSG;
80 return HC_SUCCESS;
81 }
82 int res;
83 uint8_t *selfToken = (uint8_t *)HcMalloc(ISO_TOKEN_LEN, 0);
84 if (selfToken == NULL) {
85 LOGE("Malloc for selfToken failed.");
86 return HC_ERR_ALLOC_MEMORY;
87 }
88 Uint8Buff selfTokenBuf = { selfToken, ISO_TOKEN_LEN };
89 if (params->opCode == OP_BIND) {
90 GOTO_ERR_AND_SET_RET(GetAuthIdPeerFromPayload(in, &(params->baseParams.authIdSelf),
91 &(params->baseParams.authIdPeer)), res);
92 } else {
93 GOTO_ERR_AND_SET_RET(GetAndCheckAuthIdPeer(in, &(params->baseParams.authIdSelf),
94 &(params->baseParams.authIdPeer)), res);
95 GOTO_ERR_AND_SET_RET(GetAndCheckKeyLenOnServer(in, params->keyLen), res);
96 }
97 GOTO_ERR_AND_SET_RET(GetByteFromJson(in, FIELD_ISO_SALT, params->baseParams.randPeer.val,
98 params->baseParams.randPeer.length), res);
99 res = GeneratePsk(in, params);
100 if (res != 0) {
101 LOGE("Generate psk failed, res:%d", res);
102 goto ERR;
103 }
104 res = IsoServerGenRandomAndToken(¶ms->baseParams, &selfTokenBuf);
105 if (res != 0) {
106 LOGE("IsoServerGenRandomAndToken failed, res:%d", res);
107 goto ERR;
108 }
109
110 res = PackageServerStartMessage(params, &selfTokenBuf, out);
111 if (res != HC_SUCCESS) {
112 LOGE("PackageServerStartMessage failed.");
113 goto ERR;
114 }
115
116 task->taskStatus = TASK_STATUS_CMD_RES_TOKEN;
117 *status = CONTINUE;
118 ERR:
119 HcFree(selfToken);
120 return res;
121 }
122
PackDataForCalTokenServer(const IsoParams * params,const Uint8Buff * tokenToPeer,CJson * out)123 static int PackDataForCalTokenServer(const IsoParams *params, const Uint8Buff *tokenToPeer, CJson *out)
124 {
125 int res = 0;
126 CJson *payload = NULL;
127 CJson *sendToPeer = NULL;
128
129 sendToPeer = CreateJson();
130 if (sendToPeer == NULL) {
131 LOGE("Create sendToPeer json failed.");
132 res = HC_ERR_JSON_CREATE;
133 goto ERR;
134 }
135 payload = CreateJson();
136 if (payload == NULL) {
137 LOGE("Create payload json failed.");
138 res = HC_ERR_JSON_CREATE;
139 goto ERR;
140 }
141 GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_PEER_AUTH_ID, params->baseParams.authIdSelf.val,
142 params->baseParams.authIdSelf.length), res);
143 GOTO_ERR_AND_SET_RET(AddByteToJson(payload, FIELD_RETURN_CODE_MAC, tokenToPeer->val, tokenToPeer->length), res);
144 GOTO_ERR_AND_SET_RET(AddIntToJson(payload, FIELD_OPERATION_CODE, params->opCode), res);
145 GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_AUTH_FORM, AUTH_FORM_ACCOUNT_UNRELATED), res);
146 GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_PAYLOAD, payload), res);
147 GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), res);
148 ERR:
149 FreeJson(payload);
150 FreeJson(sendToPeer);
151 return res;
152 }
153
CalTokenAndGenSessionKey(SymBaseCurTask * task,IsoParams * params,const CJson * in,CJson * out,int32_t * status)154 static int CalTokenAndGenSessionKey(SymBaseCurTask *task, IsoParams *params, const CJson *in, CJson *out,
155 int32_t *status)
156 {
157 int res;
158 uint8_t *peerToken = NULL;
159 uint8_t *tokenSelf = NULL;
160
161 if (task->taskStatus < TASK_STATUS_CMD_RES_TOKEN) {
162 LOGE("Invalid taskStatus: %d", task->taskStatus);
163 return HC_ERR_BAD_MESSAGE;
164 }
165
166 if (task->taskStatus > TASK_STATUS_CMD_RES_TOKEN) {
167 LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
168 *status = IGNORE_MSG;
169 return HC_SUCCESS;
170 }
171
172 // parse message
173 peerToken = (uint8_t *)HcMalloc(ISO_TOKEN_LEN, 0);
174 if (peerToken == NULL) {
175 LOGE("Malloc for peerToken failed.");
176 res = HC_ERR_ALLOC_MEMORY;
177 goto ERR;
178 }
179 GOTO_ERR_AND_SET_RET(GetByteFromJson(in, FIELD_TOKEN, peerToken, ISO_TOKEN_LEN), res);
180 Uint8Buff tokenFromPeer = { peerToken, ISO_TOKEN_LEN };
181
182 tokenSelf = (uint8_t *)HcMalloc(ISO_TOKEN_LEN, 0);
183 if (tokenSelf == NULL) {
184 LOGE("Malloc for tokenSelf failed.");
185 res = HC_ERR_ALLOC_MEMORY;
186 goto ERR;
187 }
188 Uint8Buff tokenToPeer = { tokenSelf, ISO_TOKEN_LEN };
189
190 // execute
191 res = IsoServerGenSessionKeyAndCalToken(¶ms->baseParams, &tokenFromPeer, &tokenToPeer);
192 if (res != 0) {
193 LOGE("IsoServerGenSessionKeyAndCalToken failed, res:%d", res);
194 goto ERR;
195 }
196
197 // package message
198 res = PackDataForCalTokenServer(params, &tokenToPeer, out);
199 if (res != 0) {
200 LOGE("PackDataForCalTokenServer failed, res:%d", res);
201 goto ERR;
202 }
203 task->taskStatus = TASK_STATUS_GEN_SESSION_KEY;
204 *status = FINISH;
205 ERR:
206 HcFree(peerToken);
207 HcFree(tokenSelf);
208 return res;
209 }
210
Process(struct SymBaseCurTaskT * task,IsoParams * params,const CJson * in,CJson * out,int32_t * status)211 static int Process(struct SymBaseCurTaskT *task, IsoParams *params, const CJson *in, CJson *out, int32_t *status)
212 {
213 int res;
214 uint32_t step = ProtocolMessageIn(in);
215 if (step == INVALID_MESSAGE) {
216 res = HC_ERR_BAD_MESSAGE;
217 goto OUT_FUNC;
218 }
219 switch (step) {
220 case STEP_ONE:
221 res = IsoServerStart(task, params, in, out, status);
222 break;
223 case STEP_TWO:
224 res = CalTokenAndGenSessionKey(task, params, in, out, status);
225 break;
226 default:
227 res = HC_ERR_BAD_MESSAGE;
228 break;
229 }
230 OUT_FUNC:
231 if (res != HC_SUCCESS) {
232 LOGE("Process step:%d failed, res: %x.", step, res);
233 return res;
234 }
235 res = ServerProtocolMessageOut(out, params->opCode, step);
236 if (res != HC_SUCCESS) {
237 LOGE("ServerProtocolMessageOut failed, res: %x.", res);
238 }
239 return res;
240 }
241
CreateProtocolServerTask(void)242 SymBaseCurTask *CreateProtocolServerTask(void)
243 {
244 IsoProtocolServerTask *task = (IsoProtocolServerTask *)HcMalloc(sizeof(IsoProtocolServerTask), 0);
245 if (task == NULL) {
246 LOGE("Malloc for IsoProtocolServerTask failed.");
247 return NULL;
248 }
249 task->taskBase.destroyTask = DestroyProtocolServerTask;
250 task->taskBase.process = Process;
251 task->taskBase.getCurTaskType = GetTaskType;
252 return (SymBaseCurTask *)task;
253 }
254