• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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_v1_protocol_task_common.h"
17 #include "das_standard_token_manager.h"
18 #include "das_task_common.h"
19 #include "hc_log.h"
20 #include "hc_types.h"
21 #include "protocol_common.h"
22 #include "pake_v1_protocol_common.h"
23 #include "pake_task_common.h"
24 #include "das_task_common.h"
25 #include "hisysevent_common.h"
26 
27 #define ASCII_CASE_DIFFERENCE_VALUE 32
28 
DestroyDasPakeV1Params(PakeParams * params)29 void DestroyDasPakeV1Params(PakeParams *params)
30 {
31     if (params == NULL) {
32         return;
33     }
34 
35     DestroyPakeV1BaseParams(&(params->baseParams));
36 
37     if (params->returnKey.val != NULL) {
38         (void)memset_s(params->returnKey.val, params->returnKey.length, 0, params->returnKey.length);
39         HcFree(params->returnKey.val);
40         params->returnKey.val = NULL;
41     }
42 
43     if (params->pseudonymExtInfo.selfNextPseudonymId.val != NULL) {
44         HcFree(params->pseudonymExtInfo.selfNextPseudonymId.val);
45         params->pseudonymExtInfo.selfNextPseudonymId.val = NULL;
46     }
47 
48     if (params->pseudonymExtInfo.selfNextPseudonymChallenge.val != NULL) {
49         HcFree(params->pseudonymExtInfo.selfNextPseudonymChallenge.val);
50         params->pseudonymExtInfo.selfNextPseudonymChallenge.val = NULL;
51     }
52 
53     if (params->pseudonymExtInfo.peerNextPseudonymId.val != NULL) {
54         HcFree(params->pseudonymExtInfo.peerNextPseudonymId.val);
55         params->pseudonymExtInfo.peerNextPseudonymId.val = NULL;
56     }
57 
58     HcFree(params->packageName);
59     params->packageName = NULL;
60 
61     HcFree(params->serviceType);
62     params->serviceType = NULL;
63 
64     HcFree(params->nonce.val);
65     params->nonce.val = NULL;
66 }
67 
AllocReturnKey(PakeParams * params,const CJson * in)68 static int32_t AllocReturnKey(PakeParams *params, const CJson *in)
69 {
70     if (params->opCode == OP_UNBIND) {
71         params->returnKey.val = NULL;
72         params->returnKey.length = 0;
73         return HC_SUCCESS;
74     }
75     int32_t res = GetIntFromJson(in, FIELD_KEY_LENGTH, (int *)&(params->returnKey.length));
76     if (res != HC_SUCCESS) {
77         LOGD("Get key length failed, use default, res: %" LOG_PUB "d", res);
78         params->returnKey.length = DEFAULT_RETURN_KEY_LENGTH;
79     }
80     if (params->returnKey.length < MIN_OUTPUT_KEY_LEN || params->returnKey.length > MAX_OUTPUT_KEY_LEN) {
81         LOGE("Output key length is invalid.");
82         return HC_ERR_INVALID_LEN;
83     }
84     res = InitSingleParam(&params->returnKey, params->returnKey.length);
85     if (res != HC_SUCCESS) {
86         LOGE("InitSingleParam for returnKey failed, res: %" LOG_PUB "d.", res);
87     }
88     return res;
89 }
90 
RemoveEscapeForExtInfo(const char * extInfoStr,char ** outExtInfoStr)91 static int32_t RemoveEscapeForExtInfo(const char *extInfoStr, char **outExtInfoStr)
92 {
93     uint32_t len = HcStrlen(extInfoStr);
94     *outExtInfoStr = (char *)HcMalloc(len + 1, 0);
95     if (*outExtInfoStr == NULL) {
96         LOGE("Failed to alloc memory for outExtInfoStr!");
97         return HC_ERR_ALLOC_MEMORY;
98     }
99     uint32_t j = 0;
100     for (uint32_t i = 0; i < len; i++) {
101         if (extInfoStr[i] == '\\') {
102             i++;
103             if (extInfoStr[i] == '\"') {
104                 (*outExtInfoStr)[j++] = '\"';
105             }
106         } else {
107             (*outExtInfoStr)[j++] = extInfoStr[i];
108         }
109     }
110     return HC_SUCCESS;
111 }
112 
GetInnerExtInfo(const Uint8Buff * extInfoBuff,Uint8Buff * innerExtInfo)113 static int32_t GetInnerExtInfo(const Uint8Buff *extInfoBuff, Uint8Buff *innerExtInfo)
114 {
115     CJson *extInfoJson = CreateJsonFromString((char *)extInfoBuff->val);
116     if (extInfoJson == NULL) {
117         LOGE("Failed to create extInfoJson!");
118         return HC_ERR_JSON_CREATE;
119     }
120     const char *innerExtInfoStr = GetStringFromJson(extInfoJson, "ExtInfo");
121     if (innerExtInfoStr == NULL) {
122         LOGE("Failed to get inner extInfo!");
123         FreeJson(extInfoJson);
124         return HC_ERR_JSON_GET;
125     }
126     char *outInnerExtStr = NULL;
127     int32_t res = RemoveEscapeForExtInfo(innerExtInfoStr, &outInnerExtStr);
128     FreeJson(extInfoJson);
129     if (res != HC_SUCCESS) {
130         LOGE("Failed to remove escape for extInfo!");
131         return res;
132     }
133     innerExtInfo->val = (uint8_t *)outInnerExtStr;
134     innerExtInfo->length = HcStrlen(outInnerExtStr) + 1;
135     return HC_SUCCESS;
136 }
137 
LoadPseudonymFlagIfNeed(PakeParams * params)138 static int32_t LoadPseudonymFlagIfNeed(PakeParams *params)
139 {
140     uint8_t peerKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
141     Uint8Buff peerKeyAlias = { peerKeyAliasVal, PAKE_KEY_ALIAS_LEN };
142     TokenManagerParams tokenParams = { 0 };
143     tokenParams.pkgName.val = (uint8_t *)params->packageName;
144     tokenParams.pkgName.length = HcStrlen(params->packageName);
145     tokenParams.serviceType.val = (uint8_t *)params->serviceType;
146     tokenParams.serviceType.length = HcStrlen(params->serviceType);
147     tokenParams.userType = params->userTypePeer;
148     tokenParams.authId = params->baseParams.idPeer;
149     int32_t res = GenerateKeyAlias(&tokenParams, &peerKeyAlias);
150     if (res != HC_SUCCESS) {
151         LOGE("Failed to generate peer key alias!");
152         return res;
153     }
154     res = ToLowerCase(&peerKeyAlias);
155     if (res != HC_SUCCESS) {
156         LOGE("Failed to convert key alias to lower case!");
157         return res;
158     }
159     Uint8Buff extInfoBuff = { NULL, 0 };
160     KeyParams keyParams = { { peerKeyAlias.val, peerKeyAlias.length, true }, true, params->baseParams.osAccountId };
161     res = params->baseParams.loader->getKeyExtInfo(&keyParams, &extInfoBuff);
162     if (res != HC_SUCCESS) {
163         LOGE("Failed to get public key extInfo!");
164         return res;
165     }
166     Uint8Buff innerExtInfo = { NULL, 0 };
167     res = GetInnerExtInfo(&extInfoBuff, &innerExtInfo);
168     FreeUint8Buff(&extInfoBuff);
169     if (res != HC_SUCCESS) {
170         LOGE("Failed to get inner extInfo!");
171         return res;
172     }
173     CJson *innerExtInfoJson = CreateJsonFromString((char *)innerExtInfo.val);
174     FreeUint8Buff(&innerExtInfo);
175     if (innerExtInfoJson == NULL) {
176         LOGE("Failed to create inner extInfo json!");
177         return HC_ERR_JSON_CREATE;
178     }
179     if (GetBoolFromJson(innerExtInfoJson, FIELD_IS_PSEUDONYM_SUPPORTED, &params->isPseudonym) != HC_SUCCESS) {
180         LOGE("Failed to get pseudonym flag from inner extInfo!");
181         FreeJson(innerExtInfoJson);
182         return HC_ERR_JSON_GET;
183     }
184     LOGI("peer support pseudonym: %" LOG_PUB "s", params->isPseudonym ? "true" : "false");
185     FreeJson(innerExtInfoJson);
186     return HC_SUCCESS;
187 }
188 
InitDasPakeV1Params(PakeParams * params,const CJson * in)189 int32_t InitDasPakeV1Params(PakeParams *params, const CJson *in)
190 {
191     int32_t osAccountId;
192     if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
193         LOGE("Failed to get osAccountId!");
194         return HC_ERR_JSON_GET;
195     }
196     int32_t res = InitPakeV1BaseParams(osAccountId, &(params->baseParams));
197     if (res != HC_SUCCESS) {
198         LOGE("InitPakeV1BaseParams failed, res: %" LOG_PUB "d.", res);
199         goto ERR;
200     }
201 
202     res = FillDasPakeParams(params, in);
203     if (res != HC_SUCCESS) {
204         LOGE("FillDasPakeParams failed, res: %" LOG_PUB "d.", res);
205         goto ERR;
206     }
207     (void)GetBoolFromJson(in, FIELD_IS_SELF_FROM_UPGRADE, &params->isSelfFromUpgrade);
208     (void)GetBoolFromJson(in, FIELD_IS_PEER_FROM_UPGRADE, &params->isPeerFromUpgrade);
209     if (params->isSelfFromUpgrade) {
210         LOGI("Self device is from upgrade!");
211     } else {
212         LOGI("Self device is not from upgrade!");
213     }
214     if (params->isPeerFromUpgrade) {
215         LOGI("peer device is from upgrade!");
216     } else {
217         LOGI("peer device is not from upgrade!");
218     }
219     if (params->opCode == AUTHENTICATE && params->isPeerFromUpgrade) {
220         (void)LoadPseudonymFlagIfNeed(params);
221     }
222 
223     res = AllocReturnKey(params, in);
224     if (res != HC_SUCCESS) {
225         LOGE("AllocReturnKey failed, res: %" LOG_PUB "d.", res);
226         goto ERR;
227     }
228 
229     return HC_SUCCESS;
230 ERR:
231     DestroyDasPakeV1Params(params);
232     return res;
233 }
234 
UpperToLowercase(Uint8Buff * hex)235 static void UpperToLowercase(Uint8Buff *hex)
236 {
237     for (uint32_t i = 0; i < hex->length; i++) {
238         if (hex->val[i] >= 'A' && hex->val[i] <= 'F') {
239             hex->val[i] += ASCII_CASE_DIFFERENCE_VALUE;
240         }
241     }
242 }
243 
ConvertPakeV1Psk(const Uint8Buff * srcPsk,PakeParams * params)244 static int32_t ConvertPakeV1Psk(const Uint8Buff *srcPsk, PakeParams *params)
245 {
246     int res = InitSingleParam(&(params->baseParams.psk), PAKE_PSK_LEN * BYTE_TO_HEX_OPER_LENGTH + 1);
247     if (res != HC_SUCCESS) {
248         LOGE("InitSingleParam for psk failed, res: %" LOG_PUB "d.", res);
249         return res;
250     }
251 
252     if (ByteToHexString(srcPsk->val, srcPsk->length, (char *)params->baseParams.psk.val,
253         params->baseParams.psk.length) != HC_SUCCESS) {
254         LOGE("Convert psk from byte to hex string failed.");
255         return HC_ERR_CONVERT_FAILED;
256     }
257     params->baseParams.psk.length = params->baseParams.psk.length - 1; // do not need include '\0' when using psk
258     (void)UpperToLowercase(&(params->baseParams.psk));
259     PRINT_DEBUG_MSG(srcPsk->val, srcPsk->length, "pskValue");
260     PRINT_SENSITIVE_DATA("pskValue", (char *)params->baseParams.psk.val);
261     return res;
262 }
263 
GeneratePskAlias(const PakeParams * params,Uint8Buff * pskKeyAlias)264 static int32_t GeneratePskAlias(const PakeParams *params, Uint8Buff *pskKeyAlias)
265 {
266     TokenManagerParams tokenParams = { 0 };
267     tokenParams.pkgName.val = (uint8_t *)params->packageName;
268     tokenParams.pkgName.length = HcStrlen(params->packageName);
269     tokenParams.serviceType.val = (uint8_t *)params->serviceType;
270     tokenParams.serviceType.length = HcStrlen(params->serviceType);
271     tokenParams.userType = KEY_ALIAS_PSK;
272     tokenParams.authId = params->baseParams.idPeer;
273     int32_t res = GenerateKeyAlias(&tokenParams, pskKeyAlias);
274     if (res != HC_SUCCESS) {
275         LOGE("GenerateKeyAlias for psk failed, res: %" LOG_PUB "d.", res);
276         return res;
277     }
278     if (params->isPeerFromUpgrade) {
279         res = ToLowerCase(pskKeyAlias);
280         if (res != HC_SUCCESS) {
281             LOGE("Failed to convert psk alias to lower case!");
282             return res;
283         }
284     }
285     return HC_SUCCESS;
286 }
287 
FillPskWithDerivedKeyHex(PakeParams * params)288 int32_t FillPskWithDerivedKeyHex(PakeParams *params)
289 {
290     int32_t res;
291     if (!(params->baseParams.isClient)) {
292         res = params->baseParams.loader->generateRandom(&(params->nonce));
293         if (res != HC_SUCCESS) {
294             LOGE("Generate nonce failed, res: %" LOG_PUB "d.", res);
295             return res;
296         }
297     }
298     uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
299     Uint8Buff pskAlias = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
300     res = GeneratePskAlias(params, &pskAlias);
301     if (res != HC_SUCCESS) {
302         return res;
303     }
304 
305     LOGI("Psk alias(HEX): %" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x****.", pskAliasVal[DEV_AUTH_ZERO],
306         pskAliasVal[DEV_AUTH_ONE], pskAliasVal[DEV_AUTH_TWO], pskAliasVal[DEV_AUTH_THREE]);
307     bool isDeStorage = params->isSelfFromUpgrade;
308     if (params->baseParams.loader->checkKeyExist(&pskAlias, isDeStorage, params->baseParams.osAccountId) !=
309         HC_SUCCESS) {
310         res = GetStandardTokenManagerInstance()->computeAndSavePsk(params);
311         if (res != HC_SUCCESS) {
312             LOGE("ComputeAndSavePsk failed, res: %" LOG_PUB "d.", res);
313             return res;
314         }
315     }
316 
317     uint8_t pskVal[PAKE_PSK_LEN] = { 0 };
318     Uint8Buff pskByte = { pskVal, PAKE_PSK_LEN };
319     Uint8Buff keyInfo = { (uint8_t *)TMP_AUTH_KEY_FACTOR, HcStrlen(TMP_AUTH_KEY_FACTOR) };
320     KeyParams keyParams = { { pskAlias.val, pskAlias.length, true }, isDeStorage, params->baseParams.osAccountId };
321     PRINT_DEBUG_MSG(params->nonce.val, params->nonce.length, "nonceValue");
322     res = params->baseParams.loader->computeHkdf(&keyParams, &(params->nonce), &keyInfo, &pskByte);
323     if (res != HC_SUCCESS) {
324         LOGE("ComputeHkdf for psk failed, res: %" LOG_PUB "d.", res);
325         FreeAndCleanKey(&(params->baseParams.psk));
326         return res;
327     }
328 
329     res = ConvertPakeV1Psk(&pskByte, params);
330     if (res != HC_SUCCESS) {
331         LOGE("ConvertPakeV1Psk failed, res: %" LOG_PUB "d.", res);
332         FreeAndCleanKey(&(params->baseParams.psk));
333     }
334     return res;
335 }
336 
FillPseudonymPskExtInfo(PseudonymPskExtInfo * extInfo,const CJson * extInfoJson)337 static int32_t FillPseudonymPskExtInfo(PseudonymPskExtInfo *extInfo, const CJson *extInfoJson)
338 {
339     uint8_t *tmpSefNextIdVal = (uint8_t *)HcMalloc(PSEUDONYM_ID_LEN, 0);
340     if (tmpSefNextIdVal == NULL) {
341         LOGE("Failed to alloc memory for self next pseudonym id!");
342         return HC_ERR_ALLOC_MEMORY;
343     }
344     if (GetByteFromJson(extInfoJson, FIELD_SELF_NEXT_PSEUDONYM_ID, tmpSefNextIdVal, PSEUDONYM_ID_LEN) != HC_SUCCESS) {
345         LOGE("Failed to get self next pseudonym id!");
346         HcFree(tmpSefNextIdVal);
347         return HC_ERR_JSON_GET;
348     }
349     uint8_t *tmpSelfNextChallengeVal = (uint8_t *)HcMalloc(PSEUDONYM_CHALLENGE_LEN, 0);
350     if (tmpSelfNextChallengeVal == NULL) {
351         LOGE("Failed to alloc memory for self next pseudonym challenge!");
352         HcFree(tmpSefNextIdVal);
353         return HC_ERR_ALLOC_MEMORY;
354     }
355     if (GetByteFromJson(extInfoJson, FIELD_SELF_NEXT_PSEUDONYM_CHALLENGE, tmpSelfNextChallengeVal,
356         PSEUDONYM_CHALLENGE_LEN) != HC_SUCCESS) {
357         LOGE("Failed to get self next pseudonym challenge!");
358         HcFree(tmpSefNextIdVal);
359         HcFree(tmpSelfNextChallengeVal);
360         return HC_ERR_JSON_GET;
361     }
362     uint8_t *tmpPeerNextIdVal = (uint8_t *)HcMalloc(PSEUDONYM_ID_LEN, 0);
363     if (tmpPeerNextIdVal == NULL) {
364         LOGE("Failed to alloc memory for peer next pseudonym id!");
365         HcFree(tmpSefNextIdVal);
366         HcFree(tmpSelfNextChallengeVal);
367         return HC_ERR_ALLOC_MEMORY;
368     }
369     if (GetByteFromJson(extInfoJson, FIELD_PEER_NEXT_PSEUDONYM_ID, tmpPeerNextIdVal, PSEUDONYM_ID_LEN) != HC_SUCCESS) {
370         LOGE("Failed to get peer next pseudonym id!");
371         HcFree(tmpSefNextIdVal);
372         HcFree(tmpSelfNextChallengeVal);
373         HcFree(tmpPeerNextIdVal);
374         return HC_ERR_JSON_GET;
375     }
376     extInfo->selfNextPseudonymId.val = tmpSefNextIdVal;
377     extInfo->selfNextPseudonymId.length = PSEUDONYM_ID_LEN;
378     extInfo->selfNextPseudonymChallenge.val = tmpSelfNextChallengeVal;
379     extInfo->selfNextPseudonymChallenge.length = PSEUDONYM_CHALLENGE_LEN;
380     extInfo->peerNextPseudonymId.val = tmpPeerNextIdVal;
381     extInfo->peerNextPseudonymId.length = PSEUDONYM_ID_LEN;
382     return HC_SUCCESS;
383 }
384 
LoadPseudonymExtInfoIfNeed(PakeParams * params)385 int32_t LoadPseudonymExtInfoIfNeed(PakeParams *params)
386 {
387     if (params == NULL) {
388         LOGE("Invalid params!");
389         return HC_ERR_INVALID_PARAMS;
390     }
391     Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
392     uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
393     Uint8Buff pskAliasBuff = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
394     int32_t res = GeneratePseudonymPskAlias(&serviceTypeBuff, &(params->baseParams.idPeer), &pskAliasBuff);
395     if (res != HC_SUCCESS) {
396         LOGE("Failed to generate pseudonym psk alias!");
397         return res;
398     }
399     res = ToLowerCase(&pskAliasBuff);
400     if (res != HC_SUCCESS) {
401         LOGE("Failed to convert key alias to lower case!");
402         return res;
403     }
404     Uint8Buff extInfoBuff = { NULL, 0 };
405     KeyParams keyParams = { { pskAliasBuff.val, pskAliasBuff.length, true }, true, params->baseParams.osAccountId };
406     res = params->baseParams.loader->getKeyExtInfo(&keyParams, &extInfoBuff);
407     if (res != HC_SUCCESS) {
408         LOGE("Failed to get pseudonym psk extInfo!");
409         return res;
410     }
411     Uint8Buff innerExtInfo = { NULL, 0 };
412     res = GetInnerExtInfo(&extInfoBuff, &innerExtInfo);
413     FreeUint8Buff(&extInfoBuff);
414     if (res != HC_SUCCESS) {
415         LOGE("Failed to get inner extInfo!");
416         return res;
417     }
418     CJson *innerExtInfoJson = CreateJsonFromString((char *)innerExtInfo.val);
419     FreeUint8Buff(&innerExtInfo);
420     if (innerExtInfoJson == NULL) {
421         LOGE("Failed to create inner extInfo json!");
422         return HC_ERR_JSON_CREATE;
423     }
424     res = FillPseudonymPskExtInfo(&params->pseudonymExtInfo, innerExtInfoJson);
425     FreeJson(innerExtInfoJson);
426     if (res != HC_SUCCESS) {
427         LOGE("Failed to fill pseudonym psk ext info!");
428     }
429     return res;
430 }
431 
CombinePseudonymChallenge(Uint8Buff * combinedChallengeBuff,const Uint8Buff * pseudonymChallengeBuff,const Uint8Buff * nextPseudonymChallengeBuff)432 static int32_t CombinePseudonymChallenge(Uint8Buff *combinedChallengeBuff, const Uint8Buff *pseudonymChallengeBuff,
433     const Uint8Buff *nextPseudonymChallengeBuff)
434 {
435     uint32_t totalLen = combinedChallengeBuff->length;
436     uint32_t usedLen = 0;
437     if (memcpy_s(combinedChallengeBuff->val, totalLen, pseudonymChallengeBuff->val,
438         pseudonymChallengeBuff->length) != EOK) {
439         LOGE("Copy pseudonym challenge failed!");
440         return HC_ERR_MEMORY_COPY;
441     }
442     usedLen = usedLen + pseudonymChallengeBuff->length;
443 
444     if (memcpy_s(combinedChallengeBuff->val + usedLen, totalLen - usedLen, nextPseudonymChallengeBuff->val,
445         nextPseudonymChallengeBuff->length) != EOK) {
446         LOGE("Copy next pseudonym challenge failed!");
447         return HC_ERR_MEMORY_COPY;
448     }
449     return HC_SUCCESS;
450 }
451 
GeneratePseudonymPskIfNotExist(const PakeParams * params)452 static int32_t GeneratePseudonymPskIfNotExist(const PakeParams *params)
453 {
454     uint8_t baseKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
455     Uint8Buff baseKeyAlias = { baseKeyAliasVal, PAKE_KEY_ALIAS_LEN };
456     TokenManagerParams tokenParams = { 0 };
457     tokenParams.pkgName.val = (uint8_t *)params->packageName;
458     tokenParams.pkgName.length = HcStrlen(params->packageName);
459     tokenParams.serviceType.val = (uint8_t *)params->serviceType;
460     tokenParams.serviceType.length = HcStrlen(params->serviceType);
461     tokenParams.userType = KEY_ALIAS_PSK;
462     tokenParams.authId = params->baseParams.idPeer;
463     int32_t res = GenerateKeyAlias(&tokenParams, &baseKeyAlias);
464     if (res != HC_SUCCESS) {
465         LOGE("Failed to generate base key alias!");
466         return res;
467     }
468     res = ToLowerCase(&baseKeyAlias);
469     if (res != HC_SUCCESS) {
470         LOGE("Failed to convert psk alias to lower case!");
471         return res;
472     }
473     uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
474     Uint8Buff pskAliasBuff = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
475     Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
476     res = GeneratePseudonymPskAlias(&serviceTypeBuff, &params->baseParams.idPeer, &pskAliasBuff);
477     if (res != HC_SUCCESS) {
478         LOGE("Failed to generate psk alias!");
479         return res;
480     }
481     res = ToLowerCase(&pskAliasBuff);
482     if (res != HC_SUCCESS) {
483         LOGE("Failed to convert pseudonym psk alias to lower case!");
484         return res;
485     }
486     if (params->baseParams.loader->checkKeyExist(&pskAliasBuff, true, params->baseParams.osAccountId) == HC_SUCCESS) {
487         LOGI("Pseudonym psk already exist.");
488         return HC_SUCCESS;
489     }
490     uint8_t outKeyVal[PAKE_PSK_LEN] = { 0 };
491     Uint8Buff outKeyBuff = { outKeyVal, PAKE_PSK_LEN };
492     KeyParams keyParams = { { baseKeyAlias.val, baseKeyAlias.length, true }, true, params->baseParams.osAccountId };
493     res = params->baseParams.loader->computePseudonymPsk(&keyParams, &pskAliasBuff, NULL, &outKeyBuff);
494     if (res != HC_SUCCESS) {
495         LOGE("Failed to compute pseudonym psk!");
496     }
497     return res;
498 }
499 
AddPseudonymIdToPayload(CJson * payload,const Uint8Buff * pseudonymIdBuff)500 static int32_t AddPseudonymIdToPayload(CJson *payload, const Uint8Buff *pseudonymIdBuff)
501 {
502     uint32_t hexLen = pseudonymIdBuff->length * BYTE_TO_HEX_OPER_LENGTH + 1;
503     char *hexStr = (char *)HcMalloc(hexLen, 0);
504     if (hexStr == NULL) {
505         LOGE("Failed to alloc memory for pseudonym id hex!");
506         return HC_ERR_ALLOC_MEMORY;
507     }
508     int32_t res = ByteToHexString(pseudonymIdBuff->val, pseudonymIdBuff->length, hexStr, hexLen);
509     if (res != HC_SUCCESS) {
510         LOGE("Failed to convert pseudonym id from byte to hex!");
511         HcFree(hexStr);
512         return res;
513     }
514     Uint8Buff hexBuff = {
515         .val = (uint8_t *)hexStr,
516         .length = HcStrlen(hexStr)
517     };
518     res = ToLowerCase(&hexBuff);
519     if (res != HC_SUCCESS) {
520         LOGE("Failed to convert pseudonym id hex to lower case!");
521         HcFree(hexStr);
522         return res;
523     }
524     if (AddStringToJson(payload, FIELD_P2P_PSEUDONYM_ID, hexStr) != HC_SUCCESS) {
525         LOGE("Failed to add pseudonym id hex to payload!");
526         HcFree(hexStr);
527         return HC_ERR_JSON_ADD;
528     }
529     HcFree(hexStr);
530     return HC_SUCCESS;
531 }
532 
AddPseudonymChallengeToPayload(CJson * payload,const Uint8Buff * pseudonymChlgBuff)533 static int32_t AddPseudonymChallengeToPayload(CJson *payload, const Uint8Buff *pseudonymChlgBuff)
534 {
535     uint32_t hexLen = pseudonymChlgBuff->length * BYTE_TO_HEX_OPER_LENGTH + 1;
536     char *hexStr = (char *)HcMalloc(hexLen, 0);
537     if (hexStr == NULL) {
538         LOGE("Failed to alloc memory for pseudonym challenge hex!");
539         return HC_ERR_ALLOC_MEMORY;
540     }
541     int32_t res = ByteToHexString(pseudonymChlgBuff->val, pseudonymChlgBuff->length, hexStr, hexLen);
542     if (res != HC_SUCCESS) {
543         LOGE("Failed to convert pseudonym challenge from byte to hex!");
544         HcFree(hexStr);
545         return res;
546     }
547     Uint8Buff hexBuff = {
548         .val = (uint8_t *)hexStr,
549         .length = HcStrlen(hexStr)
550     };
551     res = ToLowerCase(&hexBuff);
552     if (res != HC_SUCCESS) {
553         LOGE("Failed to convert pseudonym challenge hex to lower case!");
554         HcFree(hexStr);
555         return res;
556     }
557     if (AddStringToJson(payload, FIELD_PSEUDONYM_CHALLENGE, hexStr) != HC_SUCCESS) {
558         LOGE("Failed to add pseudonym challenge hex to payload!");
559         HcFree(hexStr);
560         return HC_ERR_JSON_ADD;
561     }
562     HcFree(hexStr);
563     return HC_SUCCESS;
564 }
565 
GenerateSelfPseudonymChlgAndId(const PakeParams * params,Uint8Buff * pseudonymChlgBuff,Uint8Buff * pseudonymIdBuff)566 static int32_t GenerateSelfPseudonymChlgAndId(const PakeParams *params, Uint8Buff *pseudonymChlgBuff,
567     Uint8Buff *pseudonymIdBuff)
568 {
569     int32_t res = GeneratePseudonymPskIfNotExist(params);
570     if (res != HC_SUCCESS) {
571         return res;
572     }
573     res = params->baseParams.loader->generateRandom(pseudonymChlgBuff);
574     if (res != HC_SUCCESS) {
575         LOGE("Failed to generate pseudonym challenge!");
576         return res;
577     }
578     Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
579     uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
580     Uint8Buff pskAlias = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
581     res = GeneratePseudonymPskAlias(&serviceTypeBuff, &(params->baseParams.idPeer), &pskAlias);
582     if (res != HC_SUCCESS) {
583         LOGE("Failed to generate pseudonym psk alias!");
584         return res;
585     }
586     res = ToLowerCase(&pskAlias);
587     if (res != HC_SUCCESS) {
588         LOGE("Failed to convert pseudonym psk alias to lower case!");
589         return res;
590     }
591     KeyParams pskAliasParams = { { pskAlias.val, pskAlias.length, true }, true, params->baseParams.osAccountId };
592     res = params->baseParams.loader->computeHmacWithThreeStage(&pskAliasParams, pseudonymChlgBuff, pseudonymIdBuff);
593     if (res != HC_SUCCESS) {
594         LOGE("Failed to generate pseudonym id!");
595         ReportRadarEvent(res);
596     }
597     return res;
598 }
599 
GetSelfPseudonymChlgAndIdByExtInfo(const PakeParams * params,Uint8Buff * pseudonymChallengeBuff,Uint8Buff * pseudonymIdBuff)600 static int32_t GetSelfPseudonymChlgAndIdByExtInfo(const PakeParams *params, Uint8Buff *pseudonymChallengeBuff,
601     Uint8Buff *pseudonymIdBuff)
602 {
603     if (memcpy_s(pseudonymChallengeBuff->val, pseudonymChallengeBuff->length,
604         params->pseudonymExtInfo.selfNextPseudonymChallenge.val,
605         params->pseudonymExtInfo.selfNextPseudonymChallenge.length) != EOK) {
606         LOGE("Failed to copy pseudonym challenge!");
607         return HC_ERR_MEMORY_COPY;
608     }
609     if (memcpy_s(pseudonymIdBuff->val, pseudonymIdBuff->length, params->pseudonymExtInfo.selfNextPseudonymId.val,
610         params->pseudonymExtInfo.selfNextPseudonymId.length) != EOK) {
611         LOGE("Failed to copy pseudonym id!");
612         return HC_ERR_MEMORY_COPY;
613     }
614     return HC_SUCCESS;
615 }
616 
AddPseudonymIdAndChallenge(PakeParams * params,CJson * payload)617 int32_t AddPseudonymIdAndChallenge(PakeParams *params, CJson *payload)
618 {
619     if (params == NULL || payload == NULL) {
620         LOGE("Invalid params!");
621         return HC_ERR_INVALID_PARAMS;
622     }
623     uint8_t pseudonymChallenge[PSEUDONYM_CHALLENGE_LEN] = { 0 };
624     Uint8Buff pseudonymChallengeBuff = { pseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
625     uint8_t pseudonymId[PSEUDONYM_ID_LEN] = { 0 };
626     Uint8Buff pseudonymIdBuff = { pseudonymId, PSEUDONYM_ID_LEN };
627     int32_t res;
628     if (params->pseudonymExtInfo.selfNextPseudonymId.val == NULL ||
629         params->pseudonymExtInfo.selfNextPseudonymChallenge.val == NULL) {
630         LOGW("Saved next pseudonym id or challenge is null, generate it!");
631         res = GenerateSelfPseudonymChlgAndId(params, &pseudonymChallengeBuff, &pseudonymIdBuff);
632     } else {
633         LOGI("Saved next pseudonym id or challenge is not null, use it directly.");
634         res = GetSelfPseudonymChlgAndIdByExtInfo(params, &pseudonymChallengeBuff, &pseudonymIdBuff);
635     }
636     if (res != HC_SUCCESS) {
637         return res;
638     }
639     Uint8Buff nextPseudonymChallengeBuff = { params->selfNextPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
640     res = params->baseParams.loader->generateRandom(&nextPseudonymChallengeBuff);
641     if (res != HC_SUCCESS) {
642         LOGE("Failed to generate next pseudonym challenge!");
643         return res;
644     }
645     res = AddPseudonymIdToPayload(payload, &pseudonymIdBuff);
646     if (res != HC_SUCCESS) {
647         LOGE("Failed to add pdid to payload!");
648         return res;
649     }
650     uint8_t combinedChallenge[PSEUDONYM_COMBINE_CHALLENGE_LEN] = { 0 };
651     Uint8Buff combinedChallengeBuff = { combinedChallenge, PSEUDONYM_COMBINE_CHALLENGE_LEN };
652     res = CombinePseudonymChallenge(&combinedChallengeBuff, &pseudonymChallengeBuff, &nextPseudonymChallengeBuff);
653     if (res != HC_SUCCESS) {
654         LOGE("Failed to combine pseudonym challenge!");
655         return res;
656     }
657     res = AddPseudonymChallengeToPayload(payload, &combinedChallengeBuff);
658     if (res != HC_SUCCESS) {
659         LOGE("Failed to add pdChlg to payload!");
660     }
661     return res;
662 }
663 
CheckPseudonymIdByCompute(const PakeParams * params,const Uint8Buff * peerPseudonymChallengeBuff,const Uint8Buff * peerPseudonymIdBuff,bool * isEqual)664 static int32_t CheckPseudonymIdByCompute(const PakeParams *params, const Uint8Buff *peerPseudonymChallengeBuff,
665     const Uint8Buff *peerPseudonymIdBuff, bool *isEqual)
666 {
667     int32_t res = GeneratePseudonymPskIfNotExist(params);
668     if (res != HC_SUCCESS) {
669         LOGE("Failed to generate pseudonym psk!");
670         return res;
671     }
672     Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
673     uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
674     Uint8Buff pskAlias = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
675     res = GeneratePseudonymPskAlias(&serviceTypeBuff, &(params->baseParams.idPeer), &pskAlias);
676     if (res != HC_SUCCESS) {
677         LOGE("Failed to generate pseudonym psk alias!");
678         return res;
679     }
680     res = ToLowerCase(&pskAlias);
681     if (res != HC_SUCCESS) {
682         LOGE("Failed to convert pseudonym psk alias to lower case!");
683         return res;
684     }
685     uint8_t computePeerPseudonymId[PSEUDONYM_ID_LEN] = { 0 };
686     Uint8Buff computePeerPseudonymIdBuff = { computePeerPseudonymId, PSEUDONYM_ID_LEN };
687     KeyParams pskAliasParams = { { pskAlias.val, pskAlias.length, true }, true, params->baseParams.osAccountId };
688     res = params->baseParams.loader->computeHmacWithThreeStage(&pskAliasParams, peerPseudonymChallengeBuff,
689         &computePeerPseudonymIdBuff);
690     if (res != HC_SUCCESS) {
691         LOGE("Failed to generate peer pseudonym id!");
692         ReportRadarEvent(res);
693         return res;
694     }
695     *isEqual = (memcmp(peerPseudonymIdBuff->val, computePeerPseudonymId, PSEUDONYM_ID_LEN) == 0);
696     return HC_SUCCESS;
697 }
698 
GetPeerChallenge(const CJson * payload,Uint8Buff * peerPseudonymChallengeBuff,PakeParams * params)699 static int32_t GetPeerChallenge(const CJson *payload, Uint8Buff *peerPseudonymChallengeBuff, PakeParams *params)
700 {
701     uint8_t peerChallenge[PSEUDONYM_COMBINE_CHALLENGE_LEN] = { 0 };
702     if (GetByteFromJson(payload, FIELD_PSEUDONYM_CHALLENGE, peerChallenge,
703         PSEUDONYM_COMBINE_CHALLENGE_LEN) != HC_SUCCESS) {
704         LOGE("Failed to get peer challenge!");
705         return HC_ERR_JSON_GET;
706     }
707     if (memcpy_s(peerPseudonymChallengeBuff->val, PSEUDONYM_CHALLENGE_LEN, peerChallenge,
708         PSEUDONYM_CHALLENGE_LEN) != EOK) {
709         LOGE("Failed to copy peer pseudonym challenge!");
710         return HC_ERR_MEMORY_COPY;
711     }
712     if (memcpy_s(params->peerNextPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN,
713         peerChallenge + PSEUDONYM_CHALLENGE_LEN, PSEUDONYM_CHALLENGE_LEN) != EOK) {
714         LOGE("Failed to copy peer next pseudonym challenge!");
715         return HC_ERR_MEMORY_COPY;
716     }
717     return HC_SUCCESS;
718 }
719 
CheckPseudonymId(PakeParams * params,const CJson * in)720 int32_t CheckPseudonymId(PakeParams *params, const CJson *in)
721 {
722     if (params == NULL || in == NULL) {
723         LOGE("Invalid params!");
724         return HC_ERR_INVALID_PARAMS;
725     }
726     const CJson *payload = GetObjFromJson(in, FIELD_PAYLOAD);
727     if (payload == NULL) {
728         LOGE("Failed to get payload!");
729         return HC_ERR_JSON_GET;
730     }
731     uint8_t peerPseudonymId[PSEUDONYM_ID_LEN] = { 0 };
732     if (GetByteFromJson(payload, FIELD_P2P_PSEUDONYM_ID, peerPseudonymId, PSEUDONYM_ID_LEN) != HC_SUCCESS) {
733         LOGE("Failed to get peer pseudonym id!");
734         return HC_ERR_JSON_GET;
735     }
736     uint8_t peerPseudonymChallenge[PSEUDONYM_CHALLENGE_LEN] = { 0 };
737     Uint8Buff peerPseudonymChallengeBuff = { peerPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
738     int32_t res = GetPeerChallenge(payload, &peerPseudonymChallengeBuff, params);
739     if (res != HC_SUCCESS) {
740         return res;
741     }
742     bool isEqual = false;
743     if (params->pseudonymExtInfo.peerNextPseudonymId.val != NULL) {
744         isEqual = (memcmp(peerPseudonymId, params->pseudonymExtInfo.peerNextPseudonymId.val, PSEUDONYM_ID_LEN) == 0);
745     }
746     if (!isEqual) {
747         Uint8Buff peerPseudonymIdBuff = { peerPseudonymId, PSEUDONYM_ID_LEN };
748         res = CheckPseudonymIdByCompute(params, &peerPseudonymChallengeBuff, &peerPseudonymIdBuff, &isEqual);
749         if (res != HC_SUCCESS) {
750             LOGE("Failed to check pseudonym id by compute!");
751             return res;
752         }
753     }
754     if (!isEqual) {
755         LOGE("Check pseudonym id failed!");
756         return HC_ERR_MEMORY_COMPARE;
757     }
758     LOGI("Check pseudonym id succeed.");
759     return HC_SUCCESS;
760 }
761 
GeneratePseudonymPskExtInfo(const PakeParams * params,const Uint8Buff * selfNextPseudonymIdBuff,const Uint8Buff * peerNextPseudonymIdBuff,Uint8Buff * extInfoBuff)762 static int32_t GeneratePseudonymPskExtInfo(const PakeParams *params, const Uint8Buff *selfNextPseudonymIdBuff,
763     const Uint8Buff *peerNextPseudonymIdBuff, Uint8Buff *extInfoBuff)
764 {
765     CJson *extInfoJson = CreateJson();
766     if (extInfoJson == NULL) {
767         LOGE("Failed to create extInfo json!");
768         return HC_ERR_JSON_CREATE;
769     }
770     if (AddByteToJson(extInfoJson, FIELD_SELF_NEXT_PSEUDONYM_ID, selfNextPseudonymIdBuff->val,
771         PSEUDONYM_ID_LEN) != HC_SUCCESS) {
772         LOGE("Failed to add self next pseudonym id!");
773         FreeJson(extInfoJson);
774         return HC_ERR_JSON_ADD;
775     }
776     if (AddByteToJson(extInfoJson, FIELD_SELF_NEXT_PSEUDONYM_CHALLENGE, params->selfNextPseudonymChallenge,
777         PSEUDONYM_CHALLENGE_LEN) != HC_SUCCESS) {
778         LOGE("Failed to add self next pseudonym challenge!");
779         FreeJson(extInfoJson);
780         return HC_ERR_JSON_ADD;
781     }
782     if (AddByteToJson(extInfoJson, FIELD_PEER_NEXT_PSEUDONYM_ID, peerNextPseudonymIdBuff->val,
783         PSEUDONYM_ID_LEN) != HC_SUCCESS) {
784         LOGE("Failed to add peer next pseudonym id!");
785         FreeJson(extInfoJson);
786         return HC_ERR_JSON_ADD;
787     }
788     char *extInfoJsonStr = PackJsonToString(extInfoJson);
789     FreeJson(extInfoJson);
790     if (extInfoJsonStr == NULL) {
791         LOGE("Failed to pack extInfo json to string!");
792         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
793     }
794     extInfoBuff->val = (uint8_t *)extInfoJsonStr;
795     extInfoBuff->length = HcStrlen(extInfoJsonStr) + 1;
796     return HC_SUCCESS;
797 }
798 
SaveExtInfoToPseudonymPsk(const PakeParams * params,const Uint8Buff * extInfoStrBuff,const Uint8Buff * pskAliasBuff)799 static int32_t SaveExtInfoToPseudonymPsk(const PakeParams *params, const Uint8Buff *extInfoStrBuff,
800     const Uint8Buff *pskAliasBuff)
801 {
802     uint8_t baseKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
803     Uint8Buff baseKeyAlias = { baseKeyAliasVal, PAKE_KEY_ALIAS_LEN };
804     TokenManagerParams tokenParams = { 0 };
805     tokenParams.pkgName.val = (uint8_t *)params->packageName;
806     tokenParams.pkgName.length = HcStrlen(params->packageName);
807     tokenParams.serviceType.val = (uint8_t *)params->serviceType;
808     tokenParams.serviceType.length = HcStrlen(params->serviceType);
809     tokenParams.userType = KEY_ALIAS_PSK;
810     tokenParams.authId = params->baseParams.idPeer;
811     int32_t res = GenerateKeyAlias(&tokenParams, &baseKeyAlias);
812     if (res != HC_SUCCESS) {
813         LOGE("Failed to generate psk alias!");
814         return res;
815     }
816     res = ToLowerCase(&baseKeyAlias);
817     if (res != HC_SUCCESS) {
818         LOGE("Failed to convert psk alias to lower case!");
819         return res;
820     }
821     uint8_t outKeyVal[PAKE_PSK_LEN] = { 0 };
822     Uint8Buff outKeyBuff = { outKeyVal, PAKE_PSK_LEN };
823     KeyParams keyParams = { { baseKeyAlias.val, baseKeyAlias.length, true }, true, params->baseParams.osAccountId };
824     res = params->baseParams.loader->computePseudonymPsk(&keyParams, pskAliasBuff, extInfoStrBuff,
825         &outKeyBuff);
826     if (res != HC_SUCCESS) {
827         LOGE("Failed to save extInfo to pseudonym psk!");
828     }
829     return res;
830 }
831 
SaveNextPseudonymIdAndChallenge(PakeParams * params)832 int32_t SaveNextPseudonymIdAndChallenge(PakeParams *params)
833 {
834     int32_t res = GeneratePseudonymPskIfNotExist(params);
835     if (res != HC_SUCCESS) {
836         return res;
837     }
838     Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
839     uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
840     Uint8Buff pskAlias = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
841     res = GeneratePseudonymPskAlias(&serviceTypeBuff, &(params->baseParams.idPeer), &pskAlias);
842     if (res != HC_SUCCESS) {
843         LOGE("Failed to generate pseudonym psk alias!");
844         return res;
845     }
846     res = ToLowerCase(&pskAlias);
847     if (res != HC_SUCCESS) {
848         LOGE("Failed to convert pseudonym psk alias to lower case!");
849         return res;
850     }
851     uint8_t selfNextPseudonymId[PSEUDONYM_ID_LEN] = { 0 };
852     Uint8Buff selfNextPseudonymIdBuff = { selfNextPseudonymId, PSEUDONYM_ID_LEN };
853     Uint8Buff selfNextPseudonymChallengeBuff = { params->selfNextPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
854     KeyParams pskAliasParams = { { pskAlias.val, pskAlias.length, true }, true, params->baseParams.osAccountId };
855     res = params->baseParams.loader->computeHmacWithThreeStage(&pskAliasParams, &selfNextPseudonymChallengeBuff,
856         &selfNextPseudonymIdBuff);
857     if (res != HC_SUCCESS) {
858         LOGE("Failed to compute next self pseudonym id!");
859         ReportRadarEvent(res);
860         return res;
861     }
862     uint8_t peerNextPseudonymId[PSEUDONYM_ID_LEN] = { 0 };
863     Uint8Buff peerNextPseudonymIdBuff = { peerNextPseudonymId, PSEUDONYM_ID_LEN };
864     Uint8Buff peerNextPseudonymChallengeBuff = { params->peerNextPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
865     res = params->baseParams.loader->computeHmacWithThreeStage(&pskAliasParams, &peerNextPseudonymChallengeBuff,
866         &peerNextPseudonymIdBuff);
867     if (res != HC_SUCCESS) {
868         LOGE("Failed to compute next peer pseudonym id!");
869         ReportRadarEvent(res);
870         return res;
871     }
872     Uint8Buff extInfoStrBuff = { NULL, 0 };
873     res = GeneratePseudonymPskExtInfo(params, &selfNextPseudonymIdBuff, &peerNextPseudonymIdBuff, &extInfoStrBuff);
874     if (res != HC_SUCCESS) {
875         return res;
876     }
877     res = SaveExtInfoToPseudonymPsk(params, &extInfoStrBuff, &pskAlias);
878     FreeJsonString((char *)extInfoStrBuff.val);
879     return res;
880 }