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