• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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: %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("ConstructOutJson failed, res: %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: %d.", res);
63         return res;
64     }
65     // package differentiated data
66     if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND) {
67         res = AddByteToJson(payload, FIELD_PEER_AUTH_ID, params->baseParams.idSelf.val,
68             params->baseParams.idSelf.length);
69         if (res != HC_SUCCESS) {
70             LOGE("Add idSelf failed, res: %d.", res);
71             return res;
72         }
73     }
74     if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND || params->opCode == AUTH_KEY_AGREEMENT) {
75         res = AddIntToJson(payload, FIELD_KEY_LENGTH, params->returnKey.length);
76         if (res != HC_SUCCESS) {
77             LOGE("Add keyLength failed, res: %d.", res);
78             return res;
79         }
80     }
81 
82     task->taskStatus = TASK_STATUS_CLIENT_PAKE_REQUEST;
83     *status = CONTINUE;
84     return res;
85 }
86 
ParseMsgForClientConfirm(PakeParams * params,const CJson * in)87 static int ParseMsgForClientConfirm(PakeParams *params, const CJson *in)
88 {
89     int res = ParsePakeResponseMessage(params, in);
90     if (res != HC_SUCCESS) {
91         LOGE("ParsePakeResponseMessage failed, res: %d.", res);
92         return res;
93     }
94     // parse differentiated data
95     res = GetByteFromJson(in, FIELD_CHALLENGE, params->baseParams.challengePeer.val,
96         params->baseParams.challengePeer.length);
97     if (res != HC_SUCCESS) {
98         LOGE("Get challengePeer failed, res: %d.", res);
99         return res;
100     }
101     if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND) {
102         res = GetAndCheckAuthIdPeer(in, &(params->baseParams.idSelf), &(params->baseParams.idPeer));
103         if (res != HC_SUCCESS) {
104             LOGE("GetAndCheckAuthIdPeer failed, res: %d.", res);
105             return res;
106         }
107     }
108     return res;
109 }
110 
PackageMsgForClientConfirm(PakeParams * params,CJson * out)111 static int PackageMsgForClientConfirm(PakeParams *params, CJson *out)
112 {
113     int res = ConstructOutJson(params, out);
114     if (res != HC_SUCCESS) {
115         LOGE("ConstructOutJson failed, res: %d.", res);
116         return res;
117     }
118     CJson *payload = GetObjFromJson(out, FIELD_PAYLOAD);
119     if (payload == NULL) {
120         LOGE("Get payload from json failed.");
121         return HC_ERR_JSON_GET;
122     }
123     res = PackagePakeClientConfirmData(params, payload);
124     if (res != HC_SUCCESS) {
125         LOGE("PackagePakeClientConfirmData failed, res: %d.", res);
126         return res;
127     }
128     // differentiated data
129     res = AddByteToJson(payload, FIELD_CHALLENGE, params->baseParams.challengeSelf.val,
130         params->baseParams.challengeSelf.length);
131     if (res != HC_SUCCESS) {
132         LOGE("Add challengeSelf failed, res: %d.", res);
133         return res;
134     }
135     return res;
136 }
137 
PakeClientConfirm(AsyBaseCurTask * task,PakeParams * params,const CJson * in,CJson * out,int * status)138 static int PakeClientConfirm(AsyBaseCurTask *task, PakeParams *params, const CJson *in, CJson *out, int *status)
139 {
140     int res;
141     if (task->taskStatus < TASK_STATUS_CLIENT_PAKE_REQUEST) {
142         LOGE("Invalid taskStatus: %d", task->taskStatus);
143         return HC_ERR_BAD_MESSAGE;
144     }
145     if (task->taskStatus > TASK_STATUS_CLIENT_PAKE_REQUEST) {
146         LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
147         *status = IGNORE_MSG;
148         return HC_SUCCESS;
149     }
150 
151     res = ParseMsgForClientConfirm(params, in);
152     if (res != HC_SUCCESS) {
153         LOGE("ParseMsgForClientConfirm failed, res: %d.", res);
154         return res;
155     }
156     if (params->isPskSupported && (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND)) {
157         res = FillPskWithDerivedKeyHex(params);
158         if (res != HC_SUCCESS) {
159             LOGE("FillPskWithDerivedKeyHex failed, res: %x.", res);
160             return res;
161         }
162     }
163 
164     // execute
165     res = ClientConfirmPakeV1Protocol(&(params->baseParams));
166     if (res != HC_SUCCESS) {
167         LOGE("ClientConfirmPakeV1Protocol failed, res:%d", res);
168         return res;
169     }
170 
171     res = PackageMsgForClientConfirm(params, out);
172     if (res != HC_SUCCESS) {
173         LOGE("PackageMsgForClientConfirm failed, res: %d.", res);
174         return res;
175     }
176 
177     task->taskStatus = TASK_STATUS_CLIENT_PAKE_CONFIRM;
178     *status = CONTINUE;
179     return res;
180 }
181 
PakeClientVerifyConfirm(AsyBaseCurTask * task,PakeParams * params,const CJson * in,int * status)182 static int PakeClientVerifyConfirm(AsyBaseCurTask *task, PakeParams *params, const CJson *in, int *status)
183 {
184     if (task->taskStatus < TASK_STATUS_CLIENT_PAKE_CONFIRM) {
185         LOGE("Invalid taskStatus: %d", task->taskStatus);
186         return HC_ERR_BAD_MESSAGE;
187     }
188     if (task->taskStatus > TASK_STATUS_CLIENT_PAKE_CONFIRM) {
189         LOGI("The message is repeated, ignore it, status: %d", task->taskStatus);
190         *status = IGNORE_MSG;
191         return HC_SUCCESS;
192     }
193 
194     // parse message
195     int res = ParsePakeServerConfirmMessage(params, in);
196     if (res != HC_SUCCESS) {
197         LOGE("ParsePakeServerConfirmMessage failed, res: %d.", res);
198         return res;
199     }
200 
201     // execute
202     res = ClientVerifyConfirmPakeV1Protocol(&params->baseParams);
203     if (res != HC_SUCCESS) {
204         LOGE("ClientVerifyConfirmPakeV1Protocol failed, res: %d.", res);
205         return res;
206     }
207 
208     task->taskStatus = TASK_STATUS_CLIENT_PAKE_VERIFY_CONFIRM;
209     *status = FINISH;
210     return res;
211 }
212 
Process(struct AsyBaseCurTaskT * task,PakeParams * params,const CJson * in,CJson * out,int * status)213 static int Process(struct AsyBaseCurTaskT *task, PakeParams *params, const CJson *in, CJson *out, int *status)
214 {
215     int res = HC_SUCCESS;
216     uint32_t step = ProtocolMessageIn(in);
217     if (step == INVALID_MESSAGE) {
218         res = PakeRequest(task, params, out, status);
219         step = 1;
220         goto OUT;
221     }
222 
223     step = step + 1; /* when receive peer message code, need to do next step */
224     switch (step) {
225         case STEP_TWO:
226             res = PakeClientConfirm(task, params, in, out, status);
227             break;
228         case STEP_THREE:
229             res = PakeClientVerifyConfirm(task, params, in, status);
230             break;
231         default:
232             res = HC_ERR_BAD_MESSAGE;
233             break;
234     }
235 OUT:
236     if (res != HC_SUCCESS) {
237         LOGE("Process step:%d failed, res: %x.", step, res);
238         return res;
239     }
240     if (step != STEP_THREE) {
241         res = ClientProtocolMessageOut(out, params->opCode, step);
242         if (res != HC_SUCCESS) {
243             LOGE("ClientProtocolMessageOut failed, res: %x.", res);
244         }
245     }
246     return res;
247 }
248 
CreatePakeV1ProtocolClientTask(void)249 AsyBaseCurTask *CreatePakeV1ProtocolClientTask(void)
250 {
251     PakeV1ProtocolClientTask *task = (PakeV1ProtocolClientTask *)HcMalloc(sizeof(PakeV1ProtocolClientTask), 0);
252     if (task == NULL) {
253         LOGE("Malloc for PakeV1ProtocolClientTask failed.");
254         return NULL;
255     }
256     task->taskBase.destroyTask = DestroyPakeV1ProtocolClientTask;
257     task->taskBase.process = Process;
258     task->taskBase.taskStatus = TASK_STATUS_CLIENT_PAKE_BEGIN;
259     task->taskBase.getCurTaskType = GetTaskType;
260     return (AsyBaseCurTask *)task;
261 }