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