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