• 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->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(&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 
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(&params->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(&params->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(&params->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, &params->osAccountId));
406     GOTO_IF_ERR(InitPakeV2BaseParams(&params->pakeParams));
407     GOTO_IF_ERR(InitSingleParam(&params->pakeParams.epkPeer, P256_PUBLIC_SIZE));
408     GOTO_IF_ERR(InitSingleParam(&params->pkInfoSignSelf, SIGNATURE_SIZE));
409     GOTO_IF_ERR(InitSingleParam(&params->pkInfoSignPeer, SIGNATURE_SIZE));
410     GOTO_IF_ERR(InitSingleParam(&params->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, &params->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(&params->pkInfoPeer);
458     FreeUint8Buff(&params->deviceIdPeer);
459     FreeUint8Buff(&params->devIdSelf);
460     FreeUint8Buff(&params->devIdPeer);
461     FreeUint8Buff(&params->pkInfoSelf);
462     FreeUint8Buff(&params->pkInfoSignPeer);
463     FreeUint8Buff(&params->pkInfoSignSelf);
464     DestroyPakeV2BaseParams(&params->pakeParams);
465     HcFree(params->deviceIdSelf.val);
466     params->deviceIdSelf.val = NULL;
467 }