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