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_task_common.h"
17 #include "das_module_defines.h"
18 #include "hc_log.h"
19 #include "hc_types.h"
20 #include "protocol_common.h"
21 
ConstructOutJson(const PakeParams * params,CJson * out)22 int32_t ConstructOutJson(const PakeParams *params, CJson *out)
23 {
24     int32_t res;
25     CJson *payload = NULL;
26     CJson *sendToPeer = NULL;
27 
28     payload = CreateJson();
29     if (payload == NULL) {
30         LOGE("Create payload json failed.");
31         res =  HC_ERR_ALLOC_MEMORY;
32         goto ERR;
33     }
34     sendToPeer = CreateJson();
35     if (sendToPeer == NULL) {
36         LOGE("Create sendToPeer json failed.");
37         res =  HC_ERR_ALLOC_MEMORY;
38         goto ERR;
39     }
40 
41     if (params->opCode == AUTHENTICATE) {
42         res = AddIntToJson(sendToPeer, FIELD_AUTH_FORM, AUTH_FORM_ACCOUNT_UNRELATED);
43         if (res != HC_SUCCESS) {
44             LOGE("Add authForm failed, res: %d.", res);
45             goto ERR;
46         }
47     }
48     res = AddObjToJson(sendToPeer, FIELD_PAYLOAD, payload);
49     if (res != HC_SUCCESS) {
50         LOGE("Add payload to sendToPeer failed, res: %d.", res);
51         goto ERR;
52     }
53 
54     res = AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer);
55     if (res != HC_SUCCESS) {
56         LOGE("Add sendToPeer to out failed, res: %d.", res);
57         goto ERR;
58     }
59 ERR:
60     FreeJson(payload);
61     FreeJson(sendToPeer);
62     return res;
63 }
64 
GenerateOutputKey(PakeParams * params)65 static int32_t GenerateOutputKey(PakeParams *params)
66 {
67     Uint8Buff keyInfo = { (uint8_t *)HICHAIN_RETURN_KEY, HcStrlen(HICHAIN_RETURN_KEY) };
68     KeyParams keyParam = {
69         { params->baseParams.sessionKey.val, params->baseParams.sessionKey.length, false },
70         false,
71         params->baseParams.osAccountId
72     };
73     int32_t res = params->baseParams.loader->computeHkdf(&keyParam, &(params->baseParams.salt),
74         &keyInfo, &(params->returnKey));
75     if (res != HC_SUCCESS) {
76         LOGE("Generate returnKey failed.");
77         FreeAndCleanKey(&(params->returnKey));
78     }
79     FreeAndCleanKey(&(params->baseParams.sessionKey));
80     return res;
81 }
82 
SendResultToSelf(PakeParams * params,CJson * out)83 int32_t SendResultToSelf(PakeParams *params, CJson *out)
84 {
85     int res;
86     CJson *sendToSelf = CreateJson();
87     if (sendToSelf == NULL) {
88         LOGE("Create sendToSelf json failed.");
89         res = HC_ERR_JSON_CREATE;
90         goto ERR;
91     }
92     GOTO_ERR_AND_SET_RET(AddIntToJson(sendToSelf, FIELD_OPERATION_CODE, params->opCode), res);
93     GOTO_ERR_AND_SET_RET(AddIntToJson(sendToSelf, FIELD_AUTH_FORM, AUTH_FORM_ACCOUNT_UNRELATED), res);
94 
95     if (params->returnKey.length != 0) { /* keyLen == 0 means that returnKey needn't to be generated. */
96         res = GenerateOutputKey(params);
97         if (res != HC_SUCCESS) {
98             LOGE("GenerateOutputKey failed, res: %x.", res);
99             goto ERR;
100         }
101         GOTO_ERR_AND_SET_RET(AddByteToJson(sendToSelf, FIELD_SESSION_KEY, params->returnKey.val,
102             params->returnKey.length), res);
103     }
104 
105     GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf), res);
106 ERR:
107     FreeAndCleanKey(&(params->returnKey));
108     ClearSensitiveStringInJson(sendToSelf, FIELD_SESSION_KEY);
109     FreeJson(sendToSelf);
110     return res;
111 }
112 
FillPskWithPin(PakeParams * params,const CJson * in)113 static int32_t FillPskWithPin(PakeParams *params, const CJson *in)
114 {
115     const char *pinString = GetStringFromJson(in, FIELD_PIN_CODE);
116     if (pinString == NULL) {
117         LOGE("Get pin code failed.");
118         return HC_ERR_JSON_GET;
119     }
120     if (HcStrlen(pinString) < MIN_PIN_LEN || HcStrlen(pinString) > MAX_PIN_LEN) {
121         LOGE("Pin code len is invalid.");
122         return HC_ERR_INVALID_LEN;
123     }
124 
125     int res = InitSingleParam(&(params->baseParams.psk), HcStrlen(pinString));
126     if (res != HC_SUCCESS) {
127         LOGE("InitSingleParam for psk failed, res: %d.", res);
128         return res;
129     }
130     if (memcpy_s(params->baseParams.psk.val, params->baseParams.psk.length,
131         pinString, HcStrlen(pinString)) != HC_SUCCESS) {
132         LOGE("Memcpy for pin code failed.");
133         FreeAndCleanKey(&params->baseParams.psk);
134         return HC_ERR_MEMORY_COPY;
135     }
136 
137     return HC_SUCCESS;
138 }
139 
FillAuthId(PakeParams * params,const CJson * in)140 static int32_t FillAuthId(PakeParams *params, const CJson *in)
141 {
142     const char *authId = GetStringFromJson(in, FIELD_SELF_AUTH_ID);
143     if (authId == NULL) {
144         LOGE("Get self authId failed.");
145         return HC_ERR_JSON_GET;
146     }
147     uint32_t authIdLen = HcStrlen(authId);
148     if (authIdLen == 0 || authIdLen > MAX_AUTH_ID_LEN) {
149         LOGE("Invalid self authId length: %d.", authIdLen);
150         return HC_ERR_INVALID_LEN;
151     }
152     params->baseParams.idSelf.length = authIdLen;
153     params->baseParams.idSelf.val = (uint8_t *)HcMalloc(params->baseParams.idSelf.length, 0);
154     if (params->baseParams.idSelf.val == NULL) {
155         LOGE("Malloc for idSelf failed.");
156         return HC_ERR_ALLOC_MEMORY;
157     }
158     if (memcpy_s(params->baseParams.idSelf.val, params->baseParams.idSelf.length, authId, HcStrlen(authId)) != EOK) {
159         LOGE("Memcpy for idSelf failed.");
160         return HC_ERR_MEMORY_COPY;
161     }
162 
163     if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND) {
164         authId = GetStringFromJson(in, FIELD_PEER_AUTH_ID);
165         if (authId == NULL) {
166             LOGE("Get peer authId failed.");
167             return HC_ERR_JSON_GET;
168         }
169         authIdLen = HcStrlen(authId);
170         if (authIdLen == 0 || authIdLen > MAX_AUTH_ID_LEN) {
171             LOGE("Invalid peer authId length: %d.", authIdLen);
172             return HC_ERR_INVALID_LEN;
173         }
174         params->baseParams.idPeer.length = authIdLen;
175         params->baseParams.idPeer.val = (uint8_t *)HcMalloc(params->baseParams.idPeer.length, 0);
176         if (params->baseParams.idPeer.val == NULL) {
177             LOGE("Malloc for idPeer failed.");
178             return HC_ERR_ALLOC_MEMORY;
179         }
180         if (memcpy_s(params->baseParams.idPeer.val, params->baseParams.idPeer.length,
181             authId, HcStrlen(authId)) != EOK) {
182             LOGE("Memcpy for idPeer failed.");
183             return HC_ERR_MEMORY_COPY;
184         }
185     }
186 
187     return HC_SUCCESS;
188 }
189 
FillUserType(PakeParams * params,const CJson * in)190 static int32_t FillUserType(PakeParams *params, const CJson *in)
191 {
192     if (GetIntFromJson(in, FIELD_SELF_TYPE, &(params->userType)) != HC_SUCCESS) {
193         LOGE("Get self userType failed");
194         return HC_ERR_JSON_GET;
195     }
196 
197     if (GetIntFromJson(in, FIELD_PEER_USER_TYPE, &(params->userTypePeer)) != HC_SUCCESS) {
198         LOGD("Get peer userType failed, use default.");
199         params->userTypePeer = DEVICE_TYPE_ACCESSORY;
200     }
201     return HC_SUCCESS;
202 }
203 
FillPkgNameAndServiceType(PakeParams * params,const CJson * in)204 static int32_t FillPkgNameAndServiceType(PakeParams *params, const CJson *in)
205 {
206     const char *packageName = GetStringFromJson(in, FIELD_PKG_NAME);
207     if (packageName == NULL) {
208         LOGE("Get packageName failed.");
209         return HC_ERR_JSON_GET;
210     }
211     params->packageName = (char *)HcMalloc(HcStrlen(packageName) + 1, 0);
212     if (params->packageName == NULL) {
213         LOGE("Malloc for packageName failed.");
214         return HC_ERR_ALLOC_MEMORY;
215     }
216     if (memcpy_s(params->packageName, HcStrlen(packageName) + 1, packageName, HcStrlen(packageName)) != EOK) {
217         LOGE("Memcpy for packageName failed.");
218         return HC_ERR_MEMORY_COPY;
219     }
220 
221     const char *serviceType = GetStringFromJson(in, FIELD_SERVICE_TYPE);
222     if (serviceType == NULL) {
223         LOGE("Get serviceType failed.");
224         return HC_ERR_JSON_GET;
225     }
226     params->serviceType = (char *)HcMalloc(HcStrlen(serviceType) + 1, 0);
227     if (params->serviceType == NULL) {
228         LOGE("Malloc for serviceType failed.");
229         return HC_ERR_ALLOC_MEMORY;
230     }
231     if (memcpy_s(params->serviceType, HcStrlen(serviceType) + 1, serviceType, HcStrlen(serviceType)) != EOK) {
232         LOGE("Memcpy for serviceType failed.");
233         return HC_ERR_MEMORY_COPY;
234     }
235 
236     return HC_SUCCESS;
237 }
238 
FillNonce(PakeParams * params)239 static int32_t FillNonce(PakeParams *params)
240 {
241     if (params->opCode == AUTHENTICATE || params->opCode == OP_UNBIND) {
242         params->nonce.length = PAKE_NONCE_LEN;
243         params->nonce.val = (uint8_t *)HcMalloc(params->nonce.length, 0);
244         if (params->nonce.val == NULL) {
245             LOGE("Malloc for nonce failed.");
246             return HC_ERR_ALLOC_MEMORY;
247         }
248     } else {
249         params->nonce.length = 0;
250         params->nonce.val = NULL;
251     }
252     return HC_SUCCESS;
253 }
254 
FillDasPakeParams(PakeParams * params,const CJson * in)255 int32_t FillDasPakeParams(PakeParams *params, const CJson *in)
256 {
257     if (GetIntFromJson(in, FIELD_OPERATION_CODE, &(params->opCode)) != HC_SUCCESS) {
258         LOGD("Get opCode failed, use default.");
259         params->opCode = AUTHENTICATE;
260     }
261     if (params->opCode != OP_BIND && params->opCode != OP_UNBIND &&
262         params->opCode != AUTHENTICATE && params->opCode != AUTH_KEY_AGREEMENT) {
263         LOGE("Unsupported opCode: %d.", params->opCode);
264         return HC_ERR_NOT_SUPPORT;
265     }
266 
267     if (GetBoolFromJson(in, FIELD_IS_CLIENT, &(params->baseParams.isClient)) != HC_SUCCESS) {
268         LOGE("Get isClient failed.");
269         return HC_ERR_JSON_GET;
270     }
271 
272     int res = FillNonce(params);
273     if (res != HC_SUCCESS) {
274         return res;
275     }
276 
277     if (params->opCode != AUTH_KEY_AGREEMENT) {
278         res = FillUserType(params, in);
279         if (res != HC_SUCCESS) {
280             return res;
281         }
282 
283         res = FillPkgNameAndServiceType(params, in);
284         if (res != HC_SUCCESS) {
285             return res;
286         }
287     }
288 
289     res = FillAuthId(params, in);
290     if (res != HC_SUCCESS) {
291         return res;
292     }
293 
294     if (params->opCode == OP_BIND || params->opCode == AUTH_KEY_AGREEMENT) {
295         res = FillPskWithPin(params, in);
296         if (res != HC_SUCCESS) {
297             return res;
298         }
299     }
300 
301     params->baseParams.curveType = CURVE_25519;
302 #ifdef P2P_PAKE_DL_PRIME_LEN_384
303     params->baseParams.supportedDlPrimeMod = (uint32_t)params->baseParams.supportedDlPrimeMod | DL_PRIME_MOD_384;
304 #endif
305 #ifdef P2P_PAKE_DL_PRIME_LEN_256
306     params->baseParams.supportedDlPrimeMod = (uint32_t)params->baseParams.supportedDlPrimeMod | DL_PRIME_MOD_256;
307 #endif
308     return HC_SUCCESS;
309 }
310