• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&params->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(&params->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(&params->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(&params->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(&params->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(&params->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, &params->osAccountId));
423     GOTO_IF_ERR(InitPakeV2BaseParams(params->osAccountId, &params->pakeParams));
424     GOTO_IF_ERR(InitSingleParam(&params->pakeParams.epkPeer, P256_PUBLIC_SIZE));
425     GOTO_IF_ERR(InitSingleParam(&params->pkInfoSignSelf, SIGNATURE_SIZE));
426     GOTO_IF_ERR(InitSingleParam(&params->pkInfoSignPeer, SIGNATURE_SIZE));
427     GOTO_IF_ERR(InitSingleParam(&params->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, &params->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(&params->pkInfoPeer);
463     FreeUint8Buff(&params->deviceIdPeer);
464     FreeUint8Buff(&params->devIdSelf);
465     FreeUint8Buff(&params->devIdPeer);
466     FreeUint8Buff(&params->pkInfoSelf);
467     FreeUint8Buff(&params->pkInfoSignPeer);
468     FreeUint8Buff(&params->pkInfoSignSelf);
469     FreeUint8Buff(&params->pkPeerBuff);
470     DestroyPakeV2BaseParams(&params->pakeParams);
471     HcFree(params->deviceIdSelf.val);
472     params->deviceIdSelf.val = NULL;
473 }