• 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: %" 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(&params->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 }