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(¶ms->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