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(&params->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(&params->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