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(&params->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(&params->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(&params->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(&params->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(&params->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(&params->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, &params->osAccountId));
421     GOTO_IF_ERR(InitPakeV2BaseParams(params->osAccountId, &params->pakeParams));
422     GOTO_IF_ERR(InitSingleParam(&params->pakeParams.epkPeer, P256_PUBLIC_SIZE));
423     GOTO_IF_ERR(InitSingleParam(&params->pkInfoSignSelf, SIGNATURE_SIZE));
424     GOTO_IF_ERR(InitSingleParam(&params->pkInfoSignPeer, SIGNATURE_SIZE));
425     GOTO_IF_ERR(InitSingleParam(&params->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, &params->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(&params->pkInfoPeer);
461     FreeUint8Buff(&params->deviceIdPeer);
462     FreeUint8Buff(&params->devIdSelf);
463     FreeUint8Buff(&params->devIdPeer);
464     FreeUint8Buff(&params->pkInfoSelf);
465     FreeUint8Buff(&params->pkInfoSignPeer);
466     FreeUint8Buff(&params->pkInfoSignSelf);
467     FreeUint8Buff(&params->pkPeerBuff);
468     DestroyPakeV2BaseParams(&params->pakeParams);
469     HcFree(params->deviceIdSelf.val);
470     params->deviceIdSelf.val = NULL;
471 }