• 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 
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->pkPeerBuff.val,
116         .keyLen = params->pkPeerBuff.length,
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(&params->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(&params->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(&params->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 
GetPeerPkFromPkInfo(PakeAuthParams * params,const char * pkInfoStr)270 static int32_t GetPeerPkFromPkInfo(PakeAuthParams *params, const char *pkInfoStr)
271 {
272     CJson *info = CreateJsonFromString(pkInfoStr);
273     if (info == NULL) {
274         LOGE("Failed to create json for peer pkInfo.");
275         return HC_ERR_JSON_CREATE;
276     }
277     const char *devicePk = GetStringFromJson(info, FIELD_DEVICE_PK);
278     if (devicePk == NULL) {
279         LOGE("Failed to get peer devicePk!");
280         FreeJson(info);
281         return HC_ERR_JSON_GET;
282     }
283     uint32_t pkSize = HcStrlen(devicePk) / BYTE_TO_HEX_OPER_LENGTH;
284     params->pkPeerBuff.val = (uint8_t *)HcMalloc(pkSize, 0);
285     if (params->pkPeerBuff.val == NULL) {
286         LOGE("Failed to alloc memory for peerPk!");
287         FreeJson(info);
288         return HC_ERR_ALLOC_MEMORY;
289     }
290     if (GetByteFromJson(info, FIELD_DEVICE_PK, params->pkPeerBuff.val, pkSize) != HC_SUCCESS) {
291         LOGE("Failed to get peer public key!");
292         HcFree(params->pkPeerBuff.val);
293         params->pkPeerBuff.val = NULL;
294         FreeJson(info);
295         return HC_ERR_JSON_GET;
296     }
297     FreeJson(info);
298     params->pkPeerBuff.length = pkSize;
299     return HC_SUCCESS;
300 }
301 
ExtractPeerDevId(PakeAuthParams * params,const CJson * in)302 int32_t ExtractPeerDevId(PakeAuthParams *params, const CJson *in)
303 {
304     if (params == NULL || in == NULL) {
305         LOGE("Input params is invalid.");
306         return HC_ERR_INVALID_PARAMS;
307     }
308     const char *devId = GetStringFromJson(in, FIELD_DEV_ID);
309     if (devId == NULL) {
310         LOGE("Get PeerDevId failed.");
311         return HC_ERR_JSON_GET;
312     }
313     uint32_t len = HcStrlen(devId);
314     // Peer devId type is hex string, no need to transfer.
315     if (InitCharStringBuff(&params->devIdPeer, len) != HC_SUCCESS) {
316         LOGE("InitCharStringBuff: idPeer failed.");
317         return HC_ERR_AUTH_INTERNAL;
318     }
319     if (memcpy_s(params->devIdPeer.val, params->devIdPeer.length, devId, len) != EOK) {
320         LOGE("Failed to copy devId.");
321         return HC_ERR_MEMORY_COPY;
322     }
323     return HC_SUCCESS;
324 }
325 
GetPkInfoPeer(PakeAuthParams * params,const CJson * in)326 int32_t GetPkInfoPeer(PakeAuthParams *params, const CJson *in)
327 {
328     if (params == NULL || in == NULL) {
329         LOGE("Input params is invalid.");
330         return HC_ERR_INVALID_PARAMS;
331     }
332 
333     const char *pkInfoPeerStr = GetStringFromJson(in, FIELD_AUTH_PK_INFO);
334     if (pkInfoPeerStr == NULL) {
335         LOGE("Failed to get peer pkInfo string.");
336         return HC_ERR_JSON_GET;
337     }
338     uint32_t len = HcStrlen(pkInfoPeerStr) + 1;
339     if (InitSingleParam(&params->pkInfoPeer, len) != HC_SUCCESS) {
340         LOGE("Failed to malloc for peer pkInfo.");
341         return HC_ERR_ALLOC_MEMORY;
342     }
343     if (memcpy_s(params->pkInfoPeer.val, len, pkInfoPeerStr, len) != EOK) {
344         LOGE("GetPkInfoPeer: copy pkInfoPeer failed.");
345         HcFree(params->pkInfoPeer.val);
346         params->pkInfoPeer.val = NULL;
347         return HC_ERR_ALLOC_MEMORY;
348     }
349     int32_t res = GetPeerPkFromPkInfo(params, pkInfoPeerStr);
350     if (res != HC_SUCCESS) {
351         HcFree(params->pkInfoPeer.val);
352         params->pkInfoPeer.val = NULL;
353     }
354     return res;
355 }
356 
GetAsyPubKeyInfo(PakeAuthParams * params)357 static int32_t GetAsyPubKeyInfo(PakeAuthParams *params)
358 {
359     AccountToken *token = CreateAccountToken();
360     if (token == NULL) {
361         LOGE("Failed to create token.");
362         return HC_ERR_ALLOC_MEMORY;
363     }
364     int32_t res = HC_ERR_GET_PK_INFO;
365     do {
366         if (GetAccountAuthTokenManager()->getToken(params->osAccountId, token,
367             (const char *)params->userIdSelf, (const char *)params->devIdSelf.val) != HC_SUCCESS) {
368             LOGE("Get token from local error.");
369             break;
370         }
371         uint32_t pkInfoLen = token->pkInfoStr.length;
372         if (pkInfoLen >= PUBLIC_KEY_INFO_SIZE) {
373             LOGE("Length of pkInfo from local is error.");
374             break;
375         }
376         if (InitSingleParam(&params->pkInfoSelf, pkInfoLen) != HC_SUCCESS) {
377             LOGE("InitSingleParam: pkInfoSelf failed.");
378             break;
379         }
380         if (memcpy_s(params->pkInfoSelf.val, params->pkInfoSelf.length, token->pkInfoStr.val, pkInfoLen) != EOK) {
381             LOGE("Copy pkInfoSelf failed.");
382             break;
383         }
384         if (memcpy_s(params->pkSelf, PK_SIZE, token->pkInfo.devicePk.val, token->pkInfo.devicePk.length) != EOK) {
385             LOGE("Copy pkSelf failed.");
386             break;
387         }
388         if (memcpy_s(params->pkInfoSignSelf.val, params->pkInfoSignSelf.length, token->pkInfoSignature.val,
389             token->pkInfoSignature.length) != EOK) {
390             LOGE("Copy pkInfoSignSelf failed.");
391             break;
392         }
393         params->pkInfoSignSelf.length = token->pkInfoSignature.length;
394         res = HC_SUCCESS;
395     } while (0);
396     DestroyAccountToken(token);
397     return res;
398 }
399 
FillUserIdForAuth(const CJson * in,PakeAuthParams * params)400 static int32_t FillUserIdForAuth(const CJson *in, PakeAuthParams *params)
401 {
402     const char *userIdSelf = GetStringFromJson(in, FIELD_SELF_USER_ID);
403     if (userIdSelf == NULL) {
404         LOGE("Failed to get self userId from input data.");
405         return HC_ERR_JSON_GET;
406     }
407     if (memcpy_s(params->userIdSelf, sizeof(params->userIdSelf), userIdSelf,
408         sizeof(params->userIdSelf)) != EOK) {
409         LOGE("Copy for userIdSelf failed.");
410         return HC_ERR_MEMORY_COPY;
411     }
412     return HC_SUCCESS;
413 }
414 
InitPakeAuthParams(const CJson * in,PakeAuthParams * params,const AccountVersionInfo * verInfo)415 int32_t InitPakeAuthParams(const CJson *in, PakeAuthParams *params, const AccountVersionInfo *verInfo)
416 {
417     if (in == NULL || params == NULL || verInfo == NULL) {
418         LOGE("Input params is NULL.");
419         return HC_ERR_INVALID_PARAMS;
420     }
421     const char *deviceId = GetStringFromJson(in, FIELD_SELF_DEVICE_ID);
422     if (deviceId == NULL) {
423         LOGE("Self deviceId is NULL.");
424         return HC_ERR_INVALID_PARAMS;
425     }
426     uint32_t deviceIdLen = HcStrlen(deviceId);
427     GOTO_IF_ERR(GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &params->osAccountId));
428     GOTO_IF_ERR(InitPakeV2BaseParams(&params->pakeParams));
429     GOTO_IF_ERR(InitSingleParam(&params->pakeParams.epkPeer, P256_PUBLIC_SIZE));
430     GOTO_IF_ERR(InitSingleParam(&params->pkInfoSignSelf, SIGNATURE_SIZE));
431     GOTO_IF_ERR(InitSingleParam(&params->pkInfoSignPeer, SIGNATURE_SIZE));
432     GOTO_IF_ERR(InitSingleParam(&params->pakeParams.idSelf, deviceIdLen + 1));
433     GOTO_IF_ERR(ExtractSelfDeviceId(params, in, true));
434     GOTO_IF_ERR(ExtractSelfDevId(params, in));
435     (void)memcpy_s(params->pakeParams.idSelf.val, deviceIdLen, deviceId, deviceIdLen);
436     params->pakeParams.idSelf.length = deviceIdLen;
437     GOTO_IF_ERR(FillUserIdForAuth(in, params));
438     GOTO_IF_ERR(GetBoolFromJson(in, FIELD_IS_CLIENT, &params->pakeParams.isClient));
439     GOTO_IF_ERR(GetAsyPubKeyInfo(params));
440 
441     params->pakeParams.supportedPakeAlg = verInfo->pakeAlgType;
442     params->pakeParams.curveType = verInfo->curveType;
443     params->versionNo = verInfo->versionNo;
444 #ifdef ACCOUNT_PAKE_DL_PRIME_LEN_384
445     params->pakeParams.supportedDlPrimeMod = (uint32_t)params->pakeParams.supportedDlPrimeMod | DL_PRIME_MOD_384;
446 #endif
447 #ifdef ACCOUNT_PAKE_DL_PRIME_LEN_256
448     params->pakeParams.supportedDlPrimeMod = (uint32_t)params->pakeParams.supportedDlPrimeMod | DL_PRIME_MOD_256;
449 #endif
450     return HC_SUCCESS;
451 ERR:
452     LOGE("InitPakeAuthParams failed.");
453     return HC_ERR_AUTH_INTERNAL;
454 }
455 
DestroyPakeAuthParams(PakeAuthParams * params)456 void DestroyPakeAuthParams(PakeAuthParams *params)
457 {
458     if (params == NULL) {
459         LOGE("Pointer is NULL.");
460         return;
461     }
462     (void)memset_s(params->userIdSelf, sizeof(params->userIdSelf), 0, sizeof(params->userIdSelf));
463     (void)memset_s(params->userIdPeer, sizeof(params->userIdPeer), 0, sizeof(params->userIdPeer));
464     (void)memset_s(params->pkSelf, sizeof(params->pkSelf), 0, sizeof(params->pkSelf));
465     (void)memset_s(params->pkPeer, sizeof(params->pkPeer), 0, sizeof(params->pkPeer));
466     (void)memset_s(params->pkInfoPeer.val, params->pkInfoPeer.length, 0, params->pkInfoPeer.length);
467     FreeUint8Buff(&params->pkInfoPeer);
468     FreeUint8Buff(&params->deviceIdPeer);
469     FreeUint8Buff(&params->devIdSelf);
470     FreeUint8Buff(&params->devIdPeer);
471     FreeUint8Buff(&params->pkInfoSelf);
472     FreeUint8Buff(&params->pkInfoSignPeer);
473     FreeUint8Buff(&params->pkInfoSignSelf);
474     FreeUint8Buff(&params->pkPeerBuff);
475     DestroyPakeV2BaseParams(&params->pakeParams);
476     HcFree(params->deviceIdSelf.val);
477     params->deviceIdSelf.val = NULL;
478 }