1 /*
2 * Copyright (C) 2022 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_v2_auth_task_common.h"
17
18 #include <ctype.h>
19 #include "account_module.h"
20 #include "asy_token_manager.h"
21 #include "common_defs.h"
22 #include "device_auth_defines.h"
23 #include "hc_dev_info.h"
24 #include "hc_log.h"
25 #include "hc_types.h"
26 #include "pake_v2_protocol_common.h"
27 #include "pake_v2_auth_client_task.h"
28 #include "pake_v2_auth_server_task.h"
29 #include "protocol_common.h"
30 #include "string_util.h"
31 #include "hisysevent_common.h"
32
33 #define P256_SHARED_SECRET_KEY_SIZE 32
34 #define P256_PUBLIC_SIZE 64
35 #define P256_KEY_SIZE 32
36
37 #define SHARED_KEY_ALIAS "sharedKeyAlias"
38
IsPakeV2AuthTaskSupported(void)39 bool IsPakeV2AuthTaskSupported(void)
40 {
41 return true;
42 }
43
CreatePakeV2AuthTask(const CJson * in,CJson * out,const AccountVersionInfo * verInfo)44 TaskBase *CreatePakeV2AuthTask(const CJson *in, CJson *out, const AccountVersionInfo *verInfo)
45 {
46 bool isClient = false;
47 if (GetBoolFromJson(in, FIELD_IS_CLIENT, &isClient) != HC_SUCCESS) {
48 LOGD("Get isClient from json failed.");
49 isClient = false;
50 }
51 if (isClient) {
52 return CreatePakeV2AuthClientTask(in, out, verInfo);
53 }
54 return CreatePakeV2AuthServerTask(in, out, verInfo);
55 }
56
VerifyPkSignPeer(const PakeAuthParams * params)57 int32_t VerifyPkSignPeer(const PakeAuthParams *params)
58 {
59 uint8_t *serverPkAlias = (uint8_t *)HcMalloc(SHA256_LEN, 0);
60 if (serverPkAlias == NULL) {
61 LOGE("Failed to malloc for serverPk key alias.");
62 return HC_ERR_ALLOC_MEMORY;
63 }
64 Uint8Buff serverPkAliasBuff = {
65 .val = serverPkAlias,
66 .length = SHA256_LEN
67 };
68
69 int32_t res = GetAccountAuthTokenManager()->generateKeyAlias((const char *)(params->userIdSelf),
70 (const char *)params->devIdSelf.val, &serverPkAliasBuff, true);
71 if (res != HC_SUCCESS) {
72 HcFree(serverPkAlias);
73 return res;
74 }
75
76 Uint8Buff messageBuff = {
77 .val = params->pkInfoPeer.val,
78 .length = params->pkInfoPeer.length
79 };
80 Uint8Buff peerSignBuff = {
81 .val = params->pkInfoSignPeer.val,
82 .length = params->pkInfoSignPeer.length
83 };
84 KeyParams keyParams = { { serverPkAliasBuff.val, serverPkAliasBuff.length, true }, false, params->osAccountId };
85 res = params->pakeParams.loader->verify(&keyParams, &messageBuff, P256, &peerSignBuff);
86 HcFree(serverPkAlias);
87 if (res != HC_SUCCESS) {
88 LOGE("Verify pk sign failed.");
89 return HC_ERR_VERIFY_FAILED;
90 }
91 return HC_SUCCESS;
92 }
93
GenerateEcdhSharedKey(PakeAuthParams * params)94 int32_t GenerateEcdhSharedKey(PakeAuthParams *params)
95 {
96 uint8_t *priAliasVal = (uint8_t *)HcMalloc(SHA256_LEN, 0);
97 if (priAliasVal == NULL) {
98 LOGE("Failed to malloc for self key alias.");
99 return HC_ERR_ALLOC_MEMORY;
100 }
101 Uint8Buff aliasBuff = {
102 .val = priAliasVal,
103 .length = SHA256_LEN
104 };
105 int32_t res = GetAccountAuthTokenManager()->generateKeyAlias((const char *)(params->userIdSelf),
106 (const char *)params->devIdSelf.val, &aliasBuff, false);
107 if (res != HC_SUCCESS) {
108 HcFree(priAliasVal);
109 return res;
110 }
111 uint32_t sharedKeyAliasLen = HcStrlen(SHARED_KEY_ALIAS) + 1;
112 params->pakeParams.psk.val = (uint8_t *)HcMalloc(sharedKeyAliasLen, 0);
113 if (params->pakeParams.psk.val == NULL) {
114 LOGE("Failed to malloc for psk alias.");
115 HcFree(priAliasVal);
116 return HC_ERR_ALLOC_MEMORY;
117 }
118 params->pakeParams.psk.length = sharedKeyAliasLen;
119 (void)memcpy_s(params->pakeParams.psk.val, sharedKeyAliasLen, SHARED_KEY_ALIAS, sharedKeyAliasLen);
120 KeyParams privKeyParams = { { aliasBuff.val, aliasBuff.length, true }, false, params->pakeParams.osAccountId };
121 KeyBuff pubKeyBuff = { params->pkPeerBuff.val, params->pkPeerBuff.length, false };
122 res = params->pakeParams.loader->agreeSharedSecretWithStorage(&privKeyParams, &pubKeyBuff,
123 P256, P256_SHARED_SECRET_KEY_SIZE, &(params->pakeParams.psk));
124 HcFree(priAliasVal);
125 ReportRadarEvent(res);
126 return res;
127 }
128
InitCharStringBuff(Uint8Buff * param,uint32_t len)129 static int32_t InitCharStringBuff(Uint8Buff *param, uint32_t len)
130 {
131 if (param == NULL || len == 0) {
132 LOGE("param is invalid for init.");
133 return HC_ERR_NULL_PTR;
134 }
135 if (InitSingleParam(param, len + 1) != HC_SUCCESS) {
136 return HC_ERR_ALLOC_MEMORY;
137 }
138 param->length = len;
139 return HC_SUCCESS;
140 }
141
ExtractPakePeerId(PakeAuthParams * params,const CJson * in)142 int32_t ExtractPakePeerId(PakeAuthParams *params, const CJson *in)
143 {
144 if (params == NULL || in == NULL) {
145 LOGE("Input params is invalid.");
146 return HC_ERR_INVALID_PARAMS;
147 }
148 uint32_t deviceIdPeerLen = HcStrlen((const char *)params->deviceIdPeer.val);
149 if (InitCharStringBuff(¶ms->pakeParams.idPeer,
150 params->devIdPeer.length + deviceIdPeerLen) != HC_SUCCESS) {
151 LOGE("InitCharStringBuff: idPeer failed.");
152 return HC_ERR_AUTH_INTERNAL;
153 }
154 (void)memcpy_s(params->pakeParams.idPeer.val, params->pakeParams.idPeer.length, params->devIdPeer.val,
155 params->devIdPeer.length);
156 (void)memcpy_s(params->pakeParams.idPeer.val + params->devIdPeer.length,
157 params->pakeParams.idPeer.length - params->devIdPeer.length, params->deviceIdPeer.val, deviceIdPeerLen);
158 return HC_SUCCESS;
159 }
160
ExtractPakeSelfId(PakeAuthParams * params)161 int32_t ExtractPakeSelfId(PakeAuthParams *params)
162 {
163 if (params == NULL) {
164 LOGE("Input params NULL.");
165 return HC_ERR_INVALID_PARAMS;
166 }
167 uint32_t deviceIdSelfLen = HcStrlen((const char *)params->deviceIdSelf.val);
168 if (InitCharStringBuff(¶ms->pakeParams.idSelf,
169 params->devIdSelf.length + deviceIdSelfLen) != HC_SUCCESS) {
170 LOGE("InitCharStringBuff: idSelf failed.");
171 return HC_ERR_AUTH_INTERNAL;
172 }
173
174 (void)memcpy_s(params->pakeParams.idSelf.val, params->pakeParams.idSelf.length, params->devIdSelf.val,
175 params->devIdSelf.length);
176 (void)memcpy_s(params->pakeParams.idSelf.val + params->devIdSelf.length,
177 params->pakeParams.idSelf.length - params->devIdSelf.length, params->deviceIdSelf.val, deviceIdSelfLen);
178 return HC_SUCCESS;
179 }
180
ExtractSelfDeviceId(PakeAuthParams * params,const CJson * in,bool useSelfPrefix)181 static int32_t ExtractSelfDeviceId(PakeAuthParams *params, const CJson *in, bool useSelfPrefix)
182 {
183 if (params == NULL || in == NULL) {
184 LOGE("Input params NULL.");
185 return HC_ERR_INVALID_PARAMS;
186 }
187 const char *deviceId = NULL;
188 if (useSelfPrefix) {
189 deviceId = GetStringFromJson(in, FIELD_SELF_DEVICE_ID);
190 } else {
191 deviceId = GetStringFromJson(in, FIELD_DEVICE_ID);
192 }
193 if (deviceId == NULL) {
194 LOGE("Get selfDeviceId from json failed.");
195 return HC_ERR_JSON_GET;
196 }
197 params->deviceIdSelf.length = HcStrlen(deviceId);
198 params->deviceIdSelf.val = (uint8_t *)HcMalloc(params->deviceIdSelf.length + 1, 0);
199 if (params->deviceIdSelf.val == NULL) {
200 LOGE("Failed to malloc for deviceIdSelf.");
201 return HC_ERR_ALLOC_MEMORY;
202 }
203 if (memcpy_s(params->deviceIdSelf.val, params->deviceIdSelf.length + 1,
204 deviceId, params->deviceIdSelf.length) != EOK) {
205 LOGE("Memcpy_s for deviceIdSelf failed.");
206 return HC_ERR_MEMORY_COPY;
207 }
208 return HC_SUCCESS;
209 }
210
ExtractPeerDeviceId(PakeAuthParams * params,const CJson * in)211 int32_t ExtractPeerDeviceId(PakeAuthParams *params, const CJson *in)
212 {
213 if (params == NULL || in == NULL) {
214 LOGE("Input params NULL.");
215 return HC_ERR_INVALID_PARAMS;
216 }
217 const char *deviceId = GetStringFromJson(in, FIELD_DEVICE_ID);
218 if (deviceId == NULL) {
219 LOGE("Get peer deviceId failed.");
220 return HC_ERR_JSON_GET;
221 }
222 uint32_t len = HcStrlen(deviceId);
223 if (InitCharStringBuff(¶ms->deviceIdPeer, len) != HC_SUCCESS) {
224 LOGE("InitCharStringBuff: deviceIdPeer failed.");
225 return HC_ERR_AUTH_INTERNAL;
226 }
227 if (memcpy_s(params->deviceIdPeer.val, params->deviceIdPeer.length + 1, deviceId, len) != EOK) {
228 LOGE("memcpy_s deviceId failed.");
229 return HC_ERR_MEMORY_COPY;
230 }
231 for (uint32_t i = 0; i < params->deviceIdPeer.length; i++) {
232 // Change a - f charactor to upper charactor.
233 if (params->deviceIdPeer.val[i] >= 'a' && params->deviceIdPeer.val[i] <= 'f') {
234 params->deviceIdPeer.val[i] = (uint8_t)toupper(params->deviceIdPeer.val[i]);
235 }
236 }
237 return HC_SUCCESS;
238 }
239
ExtractSelfDevId(PakeAuthParams * params,const CJson * in)240 static int32_t ExtractSelfDevId(PakeAuthParams *params, const CJson *in)
241 {
242 if (params == NULL || in == NULL) {
243 LOGE("Input params is invalid.");
244 return HC_ERR_INVALID_PARAMS;
245 }
246 const char *devIdSelf = GetStringFromJson(in, FIELD_SELF_DEV_ID);
247 if (devIdSelf == NULL) {
248 LOGE("Get devIdSelf failed.");
249 return HC_ERR_JSON_GET;
250 }
251 params->devIdSelf.length = HcStrlen(devIdSelf);
252 params->devIdSelf.val = (uint8_t *)HcMalloc(params->devIdSelf.length + 1, 0);
253 if (params->devIdSelf.val == NULL) {
254 LOGE("Malloc for devIdSelf failed.");
255 return HC_ERR_ALLOC_MEMORY;
256 }
257 if (memcpy_s(params->devIdSelf.val, params->devIdSelf.length, devIdSelf,
258 params->devIdSelf.length) != EOK) {
259 LOGE("Copy for self devId failed.");
260 return HC_ERR_MEMORY_COPY;
261 }
262 return HC_SUCCESS;
263 }
264
GetPeerPkFromPkInfo(PakeAuthParams * params,const char * pkInfoStr)265 static int32_t GetPeerPkFromPkInfo(PakeAuthParams *params, const char *pkInfoStr)
266 {
267 CJson *info = CreateJsonFromString(pkInfoStr);
268 if (info == NULL) {
269 LOGE("Failed to create json for peer pkInfo.");
270 return HC_ERR_JSON_CREATE;
271 }
272 const char *devicePk = GetStringFromJson(info, FIELD_DEVICE_PK);
273 if (devicePk == NULL) {
274 LOGE("Failed to get peer devicePk!");
275 FreeJson(info);
276 return HC_ERR_JSON_GET;
277 }
278 uint32_t pkSize = HcStrlen(devicePk) / BYTE_TO_HEX_OPER_LENGTH;
279 params->pkPeerBuff.val = (uint8_t *)HcMalloc(pkSize, 0);
280 if (params->pkPeerBuff.val == NULL) {
281 LOGE("Failed to alloc memory for peerPk!");
282 FreeJson(info);
283 return HC_ERR_ALLOC_MEMORY;
284 }
285 if (GetByteFromJson(info, FIELD_DEVICE_PK, params->pkPeerBuff.val, pkSize) != HC_SUCCESS) {
286 LOGE("Failed to get peer public key!");
287 HcFree(params->pkPeerBuff.val);
288 params->pkPeerBuff.val = NULL;
289 FreeJson(info);
290 return HC_ERR_JSON_GET;
291 }
292 FreeJson(info);
293 params->pkPeerBuff.length = pkSize;
294 return HC_SUCCESS;
295 }
296
ExtractPeerDevId(PakeAuthParams * params,const CJson * in)297 int32_t ExtractPeerDevId(PakeAuthParams *params, const CJson *in)
298 {
299 if (params == NULL || in == NULL) {
300 LOGE("Input params is invalid.");
301 return HC_ERR_INVALID_PARAMS;
302 }
303 const char *devId = GetStringFromJson(in, FIELD_DEV_ID);
304 if (devId == NULL) {
305 LOGE("Get PeerDevId failed.");
306 return HC_ERR_JSON_GET;
307 }
308 uint32_t len = HcStrlen(devId);
309 // Peer devId type is hex string, no need to transfer.
310 if (InitCharStringBuff(¶ms->devIdPeer, len) != HC_SUCCESS) {
311 LOGE("InitCharStringBuff: idPeer failed.");
312 return HC_ERR_AUTH_INTERNAL;
313 }
314 if (memcpy_s(params->devIdPeer.val, params->devIdPeer.length, devId, len) != EOK) {
315 LOGE("Failed to copy devId.");
316 return HC_ERR_MEMORY_COPY;
317 }
318 return HC_SUCCESS;
319 }
320
GetPkInfoPeer(PakeAuthParams * params,const CJson * in)321 int32_t GetPkInfoPeer(PakeAuthParams *params, const CJson *in)
322 {
323 if (params == NULL || in == NULL) {
324 LOGE("Input params is invalid.");
325 return HC_ERR_INVALID_PARAMS;
326 }
327
328 const char *pkInfoPeerStr = GetStringFromJson(in, FIELD_AUTH_PK_INFO);
329 if (pkInfoPeerStr == NULL) {
330 LOGE("Failed to get peer pkInfo string.");
331 return HC_ERR_JSON_GET;
332 }
333 uint32_t len = HcStrlen(pkInfoPeerStr) + 1;
334 if (InitSingleParam(¶ms->pkInfoPeer, len) != HC_SUCCESS) {
335 LOGE("Failed to malloc for peer pkInfo.");
336 return HC_ERR_ALLOC_MEMORY;
337 }
338 if (memcpy_s(params->pkInfoPeer.val, len, pkInfoPeerStr, len) != EOK) {
339 LOGE("GetPkInfoPeer: copy pkInfoPeer failed.");
340 HcFree(params->pkInfoPeer.val);
341 params->pkInfoPeer.val = NULL;
342 return HC_ERR_ALLOC_MEMORY;
343 }
344 int32_t res = GetPeerPkFromPkInfo(params, pkInfoPeerStr);
345 if (res != HC_SUCCESS) {
346 HcFree(params->pkInfoPeer.val);
347 params->pkInfoPeer.val = NULL;
348 }
349 return res;
350 }
351
GetAsyPubKeyInfo(PakeAuthParams * params)352 static int32_t GetAsyPubKeyInfo(PakeAuthParams *params)
353 {
354 AccountToken *token = CreateAccountToken();
355 if (token == NULL) {
356 LOGE("Failed to create token.");
357 return HC_ERR_ALLOC_MEMORY;
358 }
359 int32_t res = HC_ERR_GET_PK_INFO;
360 do {
361 if (GetAccountAuthTokenManager()->getToken(params->osAccountId, token,
362 (const char *)params->userIdSelf, (const char *)params->devIdSelf.val) != HC_SUCCESS) {
363 LOGE("Get token from local error.");
364 break;
365 }
366 uint32_t pkInfoLen = token->pkInfoStr.length;
367 if (pkInfoLen >= PUBLIC_KEY_INFO_SIZE) {
368 LOGE("Length of pkInfo from local is error.");
369 break;
370 }
371 if (InitSingleParam(¶ms->pkInfoSelf, pkInfoLen) != HC_SUCCESS) {
372 LOGE("InitSingleParam: pkInfoSelf failed.");
373 break;
374 }
375 if (memcpy_s(params->pkInfoSelf.val, params->pkInfoSelf.length, token->pkInfoStr.val, pkInfoLen) != EOK) {
376 LOGE("Copy pkInfoSelf failed.");
377 break;
378 }
379 if (memcpy_s(params->pkSelf, PK_SIZE, token->pkInfo.devicePk.val, token->pkInfo.devicePk.length) != EOK) {
380 LOGE("Copy pkSelf failed.");
381 break;
382 }
383 if (memcpy_s(params->pkInfoSignSelf.val, params->pkInfoSignSelf.length, token->pkInfoSignature.val,
384 token->pkInfoSignature.length) != EOK) {
385 LOGE("Copy pkInfoSignSelf failed.");
386 break;
387 }
388 params->pkInfoSignSelf.length = token->pkInfoSignature.length;
389 res = HC_SUCCESS;
390 } while (0);
391 DestroyAccountToken(token);
392 return res;
393 }
394
FillUserIdForAuth(const CJson * in,PakeAuthParams * params)395 static int32_t FillUserIdForAuth(const CJson *in, PakeAuthParams *params)
396 {
397 const char *userIdSelf = GetStringFromJson(in, FIELD_SELF_USER_ID);
398 if (userIdSelf == NULL) {
399 LOGE("Failed to get self userId from input data.");
400 return HC_ERR_JSON_GET;
401 }
402 if (memcpy_s(params->userIdSelf, sizeof(params->userIdSelf), userIdSelf,
403 sizeof(params->userIdSelf)) != EOK) {
404 LOGE("Copy for userIdSelf failed.");
405 return HC_ERR_MEMORY_COPY;
406 }
407 return HC_SUCCESS;
408 }
409
InitPakeAuthParams(const CJson * in,PakeAuthParams * params,const AccountVersionInfo * verInfo)410 int32_t InitPakeAuthParams(const CJson *in, PakeAuthParams *params, const AccountVersionInfo *verInfo)
411 {
412 if (in == NULL || params == NULL || verInfo == NULL) {
413 LOGE("Input params is NULL.");
414 return HC_ERR_INVALID_PARAMS;
415 }
416 const char *deviceId = GetStringFromJson(in, FIELD_SELF_DEVICE_ID);
417 if (deviceId == NULL) {
418 LOGE("Self deviceId is NULL.");
419 return HC_ERR_INVALID_PARAMS;
420 }
421 uint32_t deviceIdLen = HcStrlen(deviceId);
422 GOTO_IF_ERR(GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, ¶ms->osAccountId));
423 GOTO_IF_ERR(InitPakeV2BaseParams(params->osAccountId, ¶ms->pakeParams));
424 GOTO_IF_ERR(InitSingleParam(¶ms->pakeParams.epkPeer, P256_PUBLIC_SIZE));
425 GOTO_IF_ERR(InitSingleParam(¶ms->pkInfoSignSelf, SIGNATURE_SIZE));
426 GOTO_IF_ERR(InitSingleParam(¶ms->pkInfoSignPeer, SIGNATURE_SIZE));
427 GOTO_IF_ERR(InitSingleParam(¶ms->pakeParams.idSelf, deviceIdLen + 1));
428 GOTO_IF_ERR(ExtractSelfDeviceId(params, in, true));
429 GOTO_IF_ERR(ExtractSelfDevId(params, in));
430 (void)memcpy_s(params->pakeParams.idSelf.val, deviceIdLen, deviceId, deviceIdLen);
431 params->pakeParams.idSelf.length = deviceIdLen;
432 GOTO_IF_ERR(FillUserIdForAuth(in, params));
433 GOTO_IF_ERR(GetBoolFromJson(in, FIELD_IS_CLIENT, ¶ms->pakeParams.isClient));
434 GOTO_IF_ERR(GetAsyPubKeyInfo(params));
435
436 params->pakeParams.supportedPakeAlg = verInfo->pakeAlgType;
437 params->pakeParams.curveType = verInfo->curveType;
438 params->versionNo = verInfo->versionNo;
439 #ifdef ACCOUNT_PAKE_DL_PRIME_LEN_384
440 params->pakeParams.supportedDlPrimeMod = (uint32_t)params->pakeParams.supportedDlPrimeMod | DL_PRIME_MOD_384;
441 #endif
442 #ifdef ACCOUNT_PAKE_DL_PRIME_LEN_256
443 params->pakeParams.supportedDlPrimeMod = (uint32_t)params->pakeParams.supportedDlPrimeMod | DL_PRIME_MOD_256;
444 #endif
445 return HC_SUCCESS;
446 ERR:
447 LOGE("InitPakeAuthParams failed.");
448 return HC_ERR_AUTH_INTERNAL;
449 }
450
DestroyPakeAuthParams(PakeAuthParams * params)451 void DestroyPakeAuthParams(PakeAuthParams *params)
452 {
453 if (params == NULL) {
454 LOGE("Pointer is NULL.");
455 return;
456 }
457 (void)memset_s(params->userIdSelf, sizeof(params->userIdSelf), 0, sizeof(params->userIdSelf));
458 (void)memset_s(params->userIdPeer, sizeof(params->userIdPeer), 0, sizeof(params->userIdPeer));
459 (void)memset_s(params->pkSelf, sizeof(params->pkSelf), 0, sizeof(params->pkSelf));
460 (void)memset_s(params->pkPeer, sizeof(params->pkPeer), 0, sizeof(params->pkPeer));
461 (void)memset_s(params->pkInfoPeer.val, params->pkInfoPeer.length, 0, params->pkInfoPeer.length);
462 FreeUint8Buff(¶ms->pkInfoPeer);
463 FreeUint8Buff(¶ms->deviceIdPeer);
464 FreeUint8Buff(¶ms->devIdSelf);
465 FreeUint8Buff(¶ms->devIdPeer);
466 FreeUint8Buff(¶ms->pkInfoSelf);
467 FreeUint8Buff(¶ms->pkInfoSignPeer);
468 FreeUint8Buff(¶ms->pkInfoSignSelf);
469 FreeUint8Buff(¶ms->pkPeerBuff);
470 DestroyPakeV2BaseParams(¶ms->pakeParams);
471 HcFree(params->deviceIdSelf.val);
472 params->deviceIdSelf.val = NULL;
473 }