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