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 "pake_v1_client_protocol_task.h"
17 #include "das_task_common.h"
18 #include "hc_log.h"
19 #include "hc_types.h"
20 #include "pake_message_util.h"
21 #include "pake_v1_protocol_common.h"
22 #include "pake_v1_protocol_task_common.h"
23 #include "pake_task_common.h"
24
25 enum {
26 TASK_STATUS_CLIENT_PAKE_BEGIN = 0,
27 TASK_STATUS_CLIENT_PAKE_REQUEST,
28 TASK_STATUS_CLIENT_PAKE_CONFIRM,
29 TASK_STATUS_CLIENT_PAKE_VERIFY_CONFIRM,
30 };
31
GetTaskType(void)32 static CurTaskType GetTaskType(void)
33 {
34 return TASK_TYPE_PAKE_V1_PROTOCOL;
35 }
36
DestroyPakeV1ProtocolClientTask(struct AsyBaseCurTaskT * task)37 static void DestroyPakeV1ProtocolClientTask(struct AsyBaseCurTaskT *task)
38 {
39 HcFree(task);
40 }
41
PakeRequest(AsyBaseCurTask * task,PakeParams * params,CJson * out,int * status)42 static int PakeRequest(AsyBaseCurTask *task, PakeParams *params, CJson *out, int *status)
43 {
44 if (task->taskStatus != TASK_STATUS_CLIENT_PAKE_BEGIN) {
45 LOGI("The message is repeated, ignore it, status: %" LOG_PUB "d", task->taskStatus);
46 *status = IGNORE_MSG;
47 return HC_SUCCESS;
48 }
49
50 int res = ConstructOutJson(params, out);
51 if (res != HC_SUCCESS) {
52 LOGE("Construct out json failed, res: %" LOG_PUB "d.", res);
53 return res;
54 }
55 CJson *payload = GetObjFromJson(out, FIELD_PAYLOAD);
56 if (payload == NULL) {
57 LOGE("Get payload from json failed.");
58 return HC_ERR_JSON_GET;
59 }
60 res = PackagePakeRequestData(params, payload);
61 if (res != HC_SUCCESS) {
62 LOGE("PackagePakeRequestData failed, res: %" LOG_PUB "d.", res);
63 return res;
64 }
65 // package differentiated data
66 if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND) {
67 if (params->opCode == AUTHENTICATE && params->isPseudonym) {
68 res = AddPseudonymIdAndChallenge(params, payload);
69 } else {
70 res = AddByteToJson(payload, FIELD_PEER_AUTH_ID, params->baseParams.idSelf.val,
71 params->baseParams.idSelf.length);
72 }
73 if (res != HC_SUCCESS) {
74 LOGE("Add idSelf failed, res: %" LOG_PUB "d.", res);
75 return res;
76 }
77 }
78 if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND || params->opCode == AUTH_KEY_AGREEMENT) {
79 res = AddIntToJson(payload, FIELD_KEY_LENGTH, params->returnKey.length);
80 if (res != HC_SUCCESS) {
81 LOGE("Add keyLength failed, res: %" LOG_PUB "d.", res);
82 return res;
83 }
84 }
85
86 task->taskStatus = TASK_STATUS_CLIENT_PAKE_REQUEST;
87 *status = CONTINUE;
88 return res;
89 }
90
ParseMsgForClientConfirm(PakeParams * params,const CJson * in)91 static int ParseMsgForClientConfirm(PakeParams *params, const CJson *in)
92 {
93 int res = ParsePakeResponseMessage(params, in);
94 if (res != HC_SUCCESS) {
95 LOGE("ParsePakeResponseMessage failed, res: %" LOG_PUB "d.", res);
96 return res;
97 }
98 // parse differentiated data
99 res = GetByteFromJson(in, FIELD_CHALLENGE, params->baseParams.challengePeer.val,
100 params->baseParams.challengePeer.length);
101 if (res != HC_SUCCESS) {
102 LOGE("Get challengePeer failed, res: %" LOG_PUB "d.", res);
103 return res;
104 }
105 PRINT_DEBUG_MSG(params->baseParams.challengePeer.val, params->baseParams.challengePeer.length, "challengePeer");
106 if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND) {
107 if (params->opCode == AUTHENTICATE && params->isPseudonym) {
108 res = CheckPseudonymId(params, in);
109 } else {
110 res = GetAndCheckAuthIdPeer(in, &(params->baseParams.idSelf), &(params->baseParams.idPeer));
111 }
112 if (res != HC_SUCCESS) {
113 LOGE("GetAndCheckAuthIdPeer failed, res: %" LOG_PUB "d.", res);
114 return res;
115 }
116 }
117 return res;
118 }
119
PackageMsgForClientConfirm(PakeParams * params,CJson * out)120 static int PackageMsgForClientConfirm(PakeParams *params, CJson *out)
121 {
122 int res = ConstructOutJson(params, out);
123 if (res != HC_SUCCESS) {
124 LOGE("ConstructOutJson failed, res: %" LOG_PUB "d.", res);
125 return res;
126 }
127 CJson *payload = GetObjFromJson(out, FIELD_PAYLOAD);
128 if (payload == NULL) {
129 LOGE("Get payload from json failed.");
130 return HC_ERR_JSON_GET;
131 }
132 res = PackagePakeClientConfirmData(params, payload);
133 if (res != HC_SUCCESS) {
134 LOGE("PackagePakeClientConfirmData failed, res: %" LOG_PUB "d.", res);
135 return res;
136 }
137 // differentiated data
138 res = AddByteToJson(payload, FIELD_CHALLENGE, params->baseParams.challengeSelf.val,
139 params->baseParams.challengeSelf.length);
140 if (res != HC_SUCCESS) {
141 LOGE("Add challengeSelf failed, res: %" LOG_PUB "d.", res);
142 return res;
143 }
144 return res;
145 }
146
PakeClientConfirm(AsyBaseCurTask * task,PakeParams * params,const CJson * in,CJson * out,int * status)147 static int PakeClientConfirm(AsyBaseCurTask *task, PakeParams *params, const CJson *in, CJson *out, int *status)
148 {
149 int res;
150 if (task->taskStatus < TASK_STATUS_CLIENT_PAKE_REQUEST) {
151 LOGE("Invalid taskStatus: %" LOG_PUB "d", task->taskStatus);
152 return HC_ERR_BAD_MESSAGE;
153 }
154 if (task->taskStatus > TASK_STATUS_CLIENT_PAKE_REQUEST) {
155 LOGI("The message is repeated, ignore it, status: %" LOG_PUB "d", task->taskStatus);
156 *status = IGNORE_MSG;
157 return HC_SUCCESS;
158 }
159
160 res = ParseMsgForClientConfirm(params, in);
161 if (res != HC_SUCCESS) {
162 LOGE("ParseMsgForClientConfirm failed, res: %" LOG_PUB "d.", res);
163 return res;
164 }
165 if (params->isPskSupported && (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND)) {
166 res = FillPskWithDerivedKeyHex(params);
167 if (res != HC_SUCCESS) {
168 LOGE("FillPskWithDerivedKeyHex failed, res: %" LOG_PUB "x.", res);
169 return res;
170 }
171 }
172
173 // execute
174 res = ClientConfirmPakeV1Protocol(&(params->baseParams));
175 if (res != HC_SUCCESS) {
176 LOGE("ClientConfirmPakeV1Protocol failed, res:%" LOG_PUB "d", res);
177 return res;
178 }
179
180 res = PackageMsgForClientConfirm(params, out);
181 if (res != HC_SUCCESS) {
182 LOGE("PackageMsgForClientConfirm failed, res: %" LOG_PUB "d.", res);
183 return res;
184 }
185
186 task->taskStatus = TASK_STATUS_CLIENT_PAKE_CONFIRM;
187 *status = CONTINUE;
188 return res;
189 }
190
PakeClientVerifyConfirm(AsyBaseCurTask * task,PakeParams * params,const CJson * in,int * status)191 static int PakeClientVerifyConfirm(AsyBaseCurTask *task, PakeParams *params, const CJson *in, int *status)
192 {
193 if (task->taskStatus < TASK_STATUS_CLIENT_PAKE_CONFIRM) {
194 LOGE("Invalid taskStatus: %" LOG_PUB "d", task->taskStatus);
195 return HC_ERR_BAD_MESSAGE;
196 }
197 if (task->taskStatus > TASK_STATUS_CLIENT_PAKE_CONFIRM) {
198 LOGI("The message is repeated, ignore it, status: %" LOG_PUB "d", task->taskStatus);
199 *status = IGNORE_MSG;
200 return HC_SUCCESS;
201 }
202
203 // parse message
204 int res = ParsePakeServerConfirmMessage(params, in);
205 if (res != HC_SUCCESS) {
206 LOGE("ParsePakeServerConfirmMessage failed, res: %" LOG_PUB "d.", res);
207 return res;
208 }
209
210 // execute
211 res = ClientVerifyConfirmPakeV1Protocol(¶ms->baseParams);
212 if (res != HC_SUCCESS) {
213 LOGE("ClientVerifyConfirmPakeV1Protocol failed, res: %" LOG_PUB "d.", res);
214 return res;
215 }
216
217 task->taskStatus = TASK_STATUS_CLIENT_PAKE_VERIFY_CONFIRM;
218 *status = FINISH;
219 return res;
220 }
221
Process(struct AsyBaseCurTaskT * task,PakeParams * params,const CJson * in,CJson * out,int * status)222 static int Process(struct AsyBaseCurTaskT *task, PakeParams *params, const CJson *in, CJson *out, int *status)
223 {
224 int res = HC_SUCCESS;
225 uint32_t step = ProtocolMessageIn(in);
226 if (step == INVALID_MESSAGE) {
227 res = PakeRequest(task, params, out, status);
228 step = STEP_ONE;
229 goto OUT;
230 }
231
232 step = step + 1; /* when receive peer message code, need to do next step */
233 switch (step) {
234 case STEP_TWO:
235 res = PakeClientConfirm(task, params, in, out, status);
236 break;
237 case STEP_THREE:
238 res = PakeClientVerifyConfirm(task, params, in, status);
239 break;
240 default:
241 res = HC_ERR_BAD_MESSAGE;
242 break;
243 }
244 OUT:
245 if (res != HC_SUCCESS) {
246 LOGE("Process step:%" LOG_PUB "d failed, res: %" LOG_PUB "x.", step, res);
247 return res;
248 }
249 if (step != STEP_THREE) {
250 res = ClientProtocolMessageOut(out, params->opCode, step);
251 if (res != HC_SUCCESS) {
252 LOGE("Client protocol message out failed, res: %" LOG_PUB "x.", res);
253 }
254 }
255 return res;
256 }
257
CreatePakeV1ProtocolClientTask(void)258 AsyBaseCurTask *CreatePakeV1ProtocolClientTask(void)
259 {
260 PakeV1ProtocolClientTask *task = (PakeV1ProtocolClientTask *)HcMalloc(sizeof(PakeV1ProtocolClientTask), 0);
261 if (task == NULL) {
262 LOGE("Malloc for PakeV1ProtocolClientTask failed.");
263 return NULL;
264 }
265 task->taskBase.destroyTask = DestroyPakeV1ProtocolClientTask;
266 task->taskBase.process = Process;
267 task->taskBase.taskStatus = TASK_STATUS_CLIENT_PAKE_BEGIN;
268 task->taskBase.getCurTaskType = GetTaskType;
269 return (AsyBaseCurTask *)task;
270 }