• 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 
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: %" LOG_PUB "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: %" LOG_PUB "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: %" 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     Uint8Buff packageName = { (uint8_t *)params->packageName, HcStrlen(params->packageName) };
267     Uint8Buff serviceType = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
268     int32_t res = GenerateKeyAlias(&packageName, &serviceType, KEY_ALIAS_PSK, &(params->baseParams.idPeer),
269         pskKeyAlias);
270     if (res != HC_SUCCESS) {
271         LOGE("GenerateKeyAlias for psk failed, res: %" LOG_PUB "d.", res);
272         return res;
273     }
274     if (params->isPeerFromUpgrade) {
275         res = ToLowerCase(pskKeyAlias);
276         if (res != HC_SUCCESS) {
277             LOGE("Failed to convert psk alias to lower case!");
278             return res;
279         }
280     }
281     return HC_SUCCESS;
282 }
283 
FillPskWithDerivedKeyHex(PakeParams * params)284 int32_t FillPskWithDerivedKeyHex(PakeParams *params)
285 {
286     int32_t res;
287     if (!(params->baseParams.isClient)) {
288         res = params->baseParams.loader->generateRandom(&(params->nonce));
289         if (res != HC_SUCCESS) {
290             LOGE("Generate nonce failed, res: %" LOG_PUB "d.", res);
291             return res;
292         }
293     }
294     uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
295     Uint8Buff pskAlias = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
296     res = GeneratePskAlias(params, &pskAlias);
297     if (res != HC_SUCCESS) {
298         return res;
299     }
300 
301     LOGI("Psk alias(HEX): %" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x%" LOG_PUB "x****.", pskAliasVal[DEV_AUTH_ZERO],
302         pskAliasVal[DEV_AUTH_ONE], pskAliasVal[DEV_AUTH_TWO], pskAliasVal[DEV_AUTH_THREE]);
303     bool isDeStorage = params->isSelfFromUpgrade;
304     if (params->baseParams.loader->checkKeyExist(&pskAlias, isDeStorage, params->baseParams.osAccountId) !=
305         HC_SUCCESS) {
306         res = GetStandardTokenManagerInstance()->computeAndSavePsk(params);
307         if (res != HC_SUCCESS) {
308             LOGE("ComputeAndSavePsk failed, res: %" LOG_PUB "d.", res);
309             return res;
310         }
311     }
312 
313     uint8_t pskVal[PAKE_PSK_LEN] = { 0 };
314     Uint8Buff pskByte = { pskVal, PAKE_PSK_LEN };
315     Uint8Buff keyInfo = { (uint8_t *)TMP_AUTH_KEY_FACTOR, HcStrlen(TMP_AUTH_KEY_FACTOR) };
316     KeyParams keyParams = { { pskAlias.val, pskAlias.length, true }, isDeStorage, params->baseParams.osAccountId };
317     PRINT_DEBUG_MSG(params->nonce.val, params->nonce.length, "nonceValue");
318     res = params->baseParams.loader->computeHkdf(&keyParams, &(params->nonce), &keyInfo, &pskByte);
319     if (res != HC_SUCCESS) {
320         LOGE("ComputeHkdf for psk failed, res: %" LOG_PUB "d.", res);
321         FreeAndCleanKey(&(params->baseParams.psk));
322         return res;
323     }
324 
325     res = ConvertPakeV1Psk(&pskByte, params);
326     if (res != HC_SUCCESS) {
327         LOGE("ConvertPakeV1Psk failed, res: %" LOG_PUB "d.", res);
328         FreeAndCleanKey(&(params->baseParams.psk));
329     }
330     return res;
331 }
332 
FillPseudonymPskExtInfo(PseudonymPskExtInfo * extInfo,const CJson * extInfoJson)333 static int32_t FillPseudonymPskExtInfo(PseudonymPskExtInfo *extInfo, const CJson *extInfoJson)
334 {
335     uint8_t *tmpSefNextIdVal = (uint8_t *)HcMalloc(PSEUDONYM_ID_LEN, 0);
336     if (tmpSefNextIdVal == NULL) {
337         LOGE("Failed to alloc memory for self next pseudonym id!");
338         return HC_ERR_ALLOC_MEMORY;
339     }
340     if (GetByteFromJson(extInfoJson, FIELD_SELF_NEXT_PSEUDONYM_ID, tmpSefNextIdVal, PSEUDONYM_ID_LEN) != HC_SUCCESS) {
341         LOGE("Failed to get self next pseudonym id!");
342         HcFree(tmpSefNextIdVal);
343         return HC_ERR_JSON_GET;
344     }
345     uint8_t *tmpSelfNextChallengeVal = (uint8_t *)HcMalloc(PSEUDONYM_CHALLENGE_LEN, 0);
346     if (tmpSelfNextChallengeVal == NULL) {
347         LOGE("Failed to alloc memory for self next pseudonym challenge!");
348         HcFree(tmpSefNextIdVal);
349         return HC_ERR_ALLOC_MEMORY;
350     }
351     if (GetByteFromJson(extInfoJson, FIELD_SELF_NEXT_PSEUDONYM_CHALLENGE, tmpSelfNextChallengeVal,
352         PSEUDONYM_CHALLENGE_LEN) != HC_SUCCESS) {
353         LOGE("Failed to get self next pseudonym challenge!");
354         HcFree(tmpSefNextIdVal);
355         HcFree(tmpSelfNextChallengeVal);
356         return HC_ERR_JSON_GET;
357     }
358     uint8_t *tmpPeerNextIdVal = (uint8_t *)HcMalloc(PSEUDONYM_ID_LEN, 0);
359     if (tmpPeerNextIdVal == NULL) {
360         LOGE("Failed to alloc memory for peer next pseudonym id!");
361         HcFree(tmpSefNextIdVal);
362         HcFree(tmpSelfNextChallengeVal);
363         return HC_ERR_ALLOC_MEMORY;
364     }
365     if (GetByteFromJson(extInfoJson, FIELD_PEER_NEXT_PSEUDONYM_ID, tmpPeerNextIdVal, PSEUDONYM_ID_LEN) != HC_SUCCESS) {
366         LOGE("Failed to get peer next pseudonym id!");
367         HcFree(tmpSefNextIdVal);
368         HcFree(tmpSelfNextChallengeVal);
369         HcFree(tmpPeerNextIdVal);
370         return HC_ERR_JSON_GET;
371     }
372     extInfo->selfNextPseudonymId.val = tmpSefNextIdVal;
373     extInfo->selfNextPseudonymId.length = PSEUDONYM_ID_LEN;
374     extInfo->selfNextPseudonymChallenge.val = tmpSelfNextChallengeVal;
375     extInfo->selfNextPseudonymChallenge.length = PSEUDONYM_CHALLENGE_LEN;
376     extInfo->peerNextPseudonymId.val = tmpPeerNextIdVal;
377     extInfo->peerNextPseudonymId.length = PSEUDONYM_ID_LEN;
378     return HC_SUCCESS;
379 }
380 
LoadPseudonymExtInfoIfNeed(PakeParams * params)381 int32_t LoadPseudonymExtInfoIfNeed(PakeParams *params)
382 {
383     if (params == NULL) {
384         LOGE("Invalid params!");
385         return HC_ERR_INVALID_PARAMS;
386     }
387     Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
388     uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
389     Uint8Buff pskAliasBuff = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
390     int32_t res = GeneratePseudonymPskAlias(&serviceTypeBuff, &(params->baseParams.idPeer), &pskAliasBuff);
391     if (res != HC_SUCCESS) {
392         LOGE("Failed to generate pseudonym psk alias!");
393         return res;
394     }
395     res = ToLowerCase(&pskAliasBuff);
396     if (res != HC_SUCCESS) {
397         LOGE("Failed to convert key alias to lower case!");
398         return res;
399     }
400     Uint8Buff extInfoBuff = { NULL, 0 };
401     KeyParams keyParams = { { pskAliasBuff.val, pskAliasBuff.length, true }, true, params->baseParams.osAccountId };
402     res = params->baseParams.loader->getKeyExtInfo(&keyParams, &extInfoBuff);
403     if (res != HC_SUCCESS) {
404         LOGE("Failed to get pseudonym psk extInfo!");
405         return res;
406     }
407     Uint8Buff innerExtInfo = { NULL, 0 };
408     res = GetInnerExtInfo(&extInfoBuff, &innerExtInfo);
409     FreeUint8Buff(&extInfoBuff);
410     if (res != HC_SUCCESS) {
411         LOGE("Failed to get inner extInfo!");
412         return res;
413     }
414     CJson *innerExtInfoJson = CreateJsonFromString((char *)innerExtInfo.val);
415     FreeUint8Buff(&innerExtInfo);
416     if (innerExtInfoJson == NULL) {
417         LOGE("Failed to create inner extInfo json!");
418         return HC_ERR_JSON_CREATE;
419     }
420     res = FillPseudonymPskExtInfo(&params->pseudonymExtInfo, innerExtInfoJson);
421     FreeJson(innerExtInfoJson);
422     if (res != HC_SUCCESS) {
423         LOGE("Failed to fill pseudonym psk ext info!");
424     }
425     return res;
426 }
427 
CombinePseudonymChallenge(Uint8Buff * combinedChallengeBuff,const Uint8Buff * pseudonymChallengeBuff,const Uint8Buff * nextPseudonymChallengeBuff)428 static int32_t CombinePseudonymChallenge(Uint8Buff *combinedChallengeBuff, const Uint8Buff *pseudonymChallengeBuff,
429     const Uint8Buff *nextPseudonymChallengeBuff)
430 {
431     uint32_t totalLen = combinedChallengeBuff->length;
432     uint32_t usedLen = 0;
433     if (memcpy_s(combinedChallengeBuff->val, totalLen, pseudonymChallengeBuff->val,
434         pseudonymChallengeBuff->length) != EOK) {
435         LOGE("Copy pseudonym challenge failed!");
436         return HC_ERR_MEMORY_COPY;
437     }
438     usedLen = usedLen + pseudonymChallengeBuff->length;
439 
440     if (memcpy_s(combinedChallengeBuff->val + usedLen, totalLen - usedLen, nextPseudonymChallengeBuff->val,
441         nextPseudonymChallengeBuff->length) != EOK) {
442         LOGE("Copy next pseudonym challenge failed!");
443         return HC_ERR_MEMORY_COPY;
444     }
445     return HC_SUCCESS;
446 }
447 
GeneratePseudonymPskIfNotExist(const PakeParams * params)448 static int32_t GeneratePseudonymPskIfNotExist(const PakeParams *params)
449 {
450     uint8_t baseKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
451     Uint8Buff baseKeyAlias = { baseKeyAliasVal, PAKE_KEY_ALIAS_LEN };
452     Uint8Buff pkgNameBuff = { (uint8_t *)params->packageName, HcStrlen(params->packageName)};
453     Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
454     int32_t res = GenerateKeyAlias(&pkgNameBuff, &serviceTypeBuff, KEY_ALIAS_PSK, &params->baseParams.idPeer,
455         &baseKeyAlias);
456     if (res != HC_SUCCESS) {
457         LOGE("Failed to generate base key alias!");
458         return res;
459     }
460     res = ToLowerCase(&baseKeyAlias);
461     if (res != HC_SUCCESS) {
462         LOGE("Failed to convert psk alias to lower case!");
463         return res;
464     }
465     uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
466     Uint8Buff pskAliasBuff = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
467     res = GeneratePseudonymPskAlias(&serviceTypeBuff, &params->baseParams.idPeer, &pskAliasBuff);
468     if (res != HC_SUCCESS) {
469         LOGE("Failed to generate psk alias!");
470         return res;
471     }
472     res = ToLowerCase(&pskAliasBuff);
473     if (res != HC_SUCCESS) {
474         LOGE("Failed to convert pseudonym psk alias to lower case!");
475         return res;
476     }
477     if (params->baseParams.loader->checkKeyExist(&pskAliasBuff, true, params->baseParams.osAccountId) == HC_SUCCESS) {
478         LOGI("Pseudonym psk already exist.");
479         return HC_SUCCESS;
480     }
481     uint8_t outKeyVal[PAKE_PSK_LEN] = { 0 };
482     Uint8Buff outKeyBuff = { outKeyVal, PAKE_PSK_LEN };
483     KeyParams keyParams = { { baseKeyAlias.val, baseKeyAlias.length, true }, true, params->baseParams.osAccountId };
484     res = params->baseParams.loader->computePseudonymPsk(&keyParams, &pskAliasBuff, NULL, &outKeyBuff);
485     if (res != HC_SUCCESS) {
486         LOGE("Failed to compute pseudonym psk!");
487     }
488     return res;
489 }
490 
AddPseudonymIdToPayload(CJson * payload,const Uint8Buff * pseudonymIdBuff)491 static int32_t AddPseudonymIdToPayload(CJson *payload, const Uint8Buff *pseudonymIdBuff)
492 {
493     uint32_t hexLen = pseudonymIdBuff->length * BYTE_TO_HEX_OPER_LENGTH + 1;
494     char *hexStr = (char *)HcMalloc(hexLen, 0);
495     if (hexStr == NULL) {
496         LOGE("Failed to alloc memory for pseudonym id hex!");
497         return HC_ERR_ALLOC_MEMORY;
498     }
499     int32_t res = ByteToHexString(pseudonymIdBuff->val, pseudonymIdBuff->length, hexStr, hexLen);
500     if (res != HC_SUCCESS) {
501         LOGE("Failed to convert pseudonym id from byte to hex!");
502         HcFree(hexStr);
503         return res;
504     }
505     Uint8Buff hexBuff = {
506         .val = (uint8_t *)hexStr,
507         .length = HcStrlen(hexStr)
508     };
509     res = ToLowerCase(&hexBuff);
510     if (res != HC_SUCCESS) {
511         LOGE("Failed to convert pseudonym id hex to lower case!");
512         HcFree(hexStr);
513         return res;
514     }
515     if (AddStringToJson(payload, FIELD_P2P_PSEUDONYM_ID, hexStr) != HC_SUCCESS) {
516         LOGE("Failed to add pseudonym id hex to payload!");
517         HcFree(hexStr);
518         return HC_ERR_JSON_ADD;
519     }
520     HcFree(hexStr);
521     return HC_SUCCESS;
522 }
523 
AddPseudonymChallengeToPayload(CJson * payload,const Uint8Buff * pseudonymChlgBuff)524 static int32_t AddPseudonymChallengeToPayload(CJson *payload, const Uint8Buff *pseudonymChlgBuff)
525 {
526     uint32_t hexLen = pseudonymChlgBuff->length * BYTE_TO_HEX_OPER_LENGTH + 1;
527     char *hexStr = (char *)HcMalloc(hexLen, 0);
528     if (hexStr == NULL) {
529         LOGE("Failed to alloc memory for pseudonym challenge hex!");
530         return HC_ERR_ALLOC_MEMORY;
531     }
532     int32_t res = ByteToHexString(pseudonymChlgBuff->val, pseudonymChlgBuff->length, hexStr, hexLen);
533     if (res != HC_SUCCESS) {
534         LOGE("Failed to convert pseudonym challenge from byte to hex!");
535         HcFree(hexStr);
536         return res;
537     }
538     Uint8Buff hexBuff = {
539         .val = (uint8_t *)hexStr,
540         .length = HcStrlen(hexStr)
541     };
542     res = ToLowerCase(&hexBuff);
543     if (res != HC_SUCCESS) {
544         LOGE("Failed to convert pseudonym challenge hex to lower case!");
545         HcFree(hexStr);
546         return res;
547     }
548     if (AddStringToJson(payload, FIELD_PSEUDONYM_CHALLENGE, hexStr) != HC_SUCCESS) {
549         LOGE("Failed to add pseudonym challenge hex to payload!");
550         HcFree(hexStr);
551         return HC_ERR_JSON_ADD;
552     }
553     HcFree(hexStr);
554     return HC_SUCCESS;
555 }
556 
GenerateSelfPseudonymChlgAndId(const PakeParams * params,Uint8Buff * pseudonymChlgBuff,Uint8Buff * pseudonymIdBuff)557 static int32_t GenerateSelfPseudonymChlgAndId(const PakeParams *params, Uint8Buff *pseudonymChlgBuff,
558     Uint8Buff *pseudonymIdBuff)
559 {
560     int32_t res = GeneratePseudonymPskIfNotExist(params);
561     if (res != HC_SUCCESS) {
562         return res;
563     }
564     res = params->baseParams.loader->generateRandom(pseudonymChlgBuff);
565     if (res != HC_SUCCESS) {
566         LOGE("Failed to generate pseudonym challenge!");
567         return res;
568     }
569     Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
570     uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
571     Uint8Buff pskAlias = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
572     res = GeneratePseudonymPskAlias(&serviceTypeBuff, &(params->baseParams.idPeer), &pskAlias);
573     if (res != HC_SUCCESS) {
574         LOGE("Failed to generate pseudonym psk alias!");
575         return res;
576     }
577     res = ToLowerCase(&pskAlias);
578     if (res != HC_SUCCESS) {
579         LOGE("Failed to convert pseudonym psk alias to lower case!");
580         return res;
581     }
582     KeyParams pskAliasParams = { { pskAlias.val, pskAlias.length, true }, true, params->baseParams.osAccountId };
583     res = params->baseParams.loader->computeHmacWithThreeStage(&pskAliasParams, pseudonymChlgBuff, pseudonymIdBuff);
584     if (res != HC_SUCCESS) {
585         LOGE("Failed to generate pseudonym id!");
586     }
587     return res;
588 }
589 
GetSelfPseudonymChlgAndIdByExtInfo(const PakeParams * params,Uint8Buff * pseudonymChallengeBuff,Uint8Buff * pseudonymIdBuff)590 static int32_t GetSelfPseudonymChlgAndIdByExtInfo(const PakeParams *params, Uint8Buff *pseudonymChallengeBuff,
591     Uint8Buff *pseudonymIdBuff)
592 {
593     if (memcpy_s(pseudonymChallengeBuff->val, pseudonymChallengeBuff->length,
594         params->pseudonymExtInfo.selfNextPseudonymChallenge.val,
595         params->pseudonymExtInfo.selfNextPseudonymChallenge.length) != EOK) {
596         LOGE("Failed to copy pseudonym challenge!");
597         return HC_ERR_MEMORY_COPY;
598     }
599     if (memcpy_s(pseudonymIdBuff->val, pseudonymIdBuff->length, params->pseudonymExtInfo.selfNextPseudonymId.val,
600         params->pseudonymExtInfo.selfNextPseudonymId.length) != EOK) {
601         LOGE("Failed to copy pseudonym id!");
602         return HC_ERR_MEMORY_COPY;
603     }
604     return HC_SUCCESS;
605 }
606 
AddPseudonymIdAndChallenge(PakeParams * params,CJson * payload)607 int32_t AddPseudonymIdAndChallenge(PakeParams *params, CJson *payload)
608 {
609     if (params == NULL || payload == NULL) {
610         LOGE("Invalid params!");
611         return HC_ERR_INVALID_PARAMS;
612     }
613     uint8_t pseudonymChallenge[PSEUDONYM_CHALLENGE_LEN] = { 0 };
614     Uint8Buff pseudonymChallengeBuff = { pseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
615     uint8_t pseudonymId[PSEUDONYM_ID_LEN] = { 0 };
616     Uint8Buff pseudonymIdBuff = { pseudonymId, PSEUDONYM_ID_LEN };
617     int32_t res;
618     if (params->pseudonymExtInfo.selfNextPseudonymId.val == NULL ||
619         params->pseudonymExtInfo.selfNextPseudonymChallenge.val == NULL) {
620         LOGW("Saved next pseudonym id or challenge is null, generate it!");
621         res = GenerateSelfPseudonymChlgAndId(params, &pseudonymChallengeBuff, &pseudonymIdBuff);
622     } else {
623         LOGI("Saved next pseudonym id or challenge is not null, use it directly.");
624         res = GetSelfPseudonymChlgAndIdByExtInfo(params, &pseudonymChallengeBuff, &pseudonymIdBuff);
625     }
626     if (res != HC_SUCCESS) {
627         return res;
628     }
629     Uint8Buff nextPseudonymChallengeBuff = { params->selfNextPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
630     res = params->baseParams.loader->generateRandom(&nextPseudonymChallengeBuff);
631     if (res != HC_SUCCESS) {
632         LOGE("Failed to generate next pseudonym challenge!");
633         return res;
634     }
635     res = AddPseudonymIdToPayload(payload, &pseudonymIdBuff);
636     if (res != HC_SUCCESS) {
637         LOGE("Failed to add pdid to payload!");
638         return res;
639     }
640     uint8_t combinedChallenge[PSEUDONYM_COMBINE_CHALLENGE_LEN] = { 0 };
641     Uint8Buff combinedChallengeBuff = { combinedChallenge, PSEUDONYM_COMBINE_CHALLENGE_LEN };
642     res = CombinePseudonymChallenge(&combinedChallengeBuff, &pseudonymChallengeBuff, &nextPseudonymChallengeBuff);
643     if (res != HC_SUCCESS) {
644         LOGE("Failed to combine pseudonym challenge!");
645         return res;
646     }
647     res = AddPseudonymChallengeToPayload(payload, &combinedChallengeBuff);
648     if (res != HC_SUCCESS) {
649         LOGE("Failed to add pdChlg to payload!");
650     }
651     return res;
652 }
653 
CheckPseudonymIdByCompute(const PakeParams * params,const Uint8Buff * peerPseudonymChallengeBuff,const Uint8Buff * peerPseudonymIdBuff,bool * isEqual)654 static int32_t CheckPseudonymIdByCompute(const PakeParams *params, const Uint8Buff *peerPseudonymChallengeBuff,
655     const Uint8Buff *peerPseudonymIdBuff, bool *isEqual)
656 {
657     int32_t res = GeneratePseudonymPskIfNotExist(params);
658     if (res != HC_SUCCESS) {
659         LOGE("Failed to generate pseudonym psk!");
660         return res;
661     }
662     Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
663     uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
664     Uint8Buff pskAlias = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
665     res = GeneratePseudonymPskAlias(&serviceTypeBuff, &(params->baseParams.idPeer), &pskAlias);
666     if (res != HC_SUCCESS) {
667         LOGE("Failed to generate pseudonym psk alias!");
668         return res;
669     }
670     res = ToLowerCase(&pskAlias);
671     if (res != HC_SUCCESS) {
672         LOGE("Failed to convert pseudonym psk alias to lower case!");
673         return res;
674     }
675     uint8_t computePeerPseudonymId[PSEUDONYM_ID_LEN] = { 0 };
676     Uint8Buff computePeerPseudonymIdBuff = { computePeerPseudonymId, PSEUDONYM_ID_LEN };
677     KeyParams pskAliasParams = { { pskAlias.val, pskAlias.length, true }, true, params->baseParams.osAccountId };
678     res = params->baseParams.loader->computeHmacWithThreeStage(&pskAliasParams, peerPseudonymChallengeBuff,
679         &computePeerPseudonymIdBuff);
680     if (res != HC_SUCCESS) {
681         LOGE("Failed to generate peer pseudonym id!");
682         return res;
683     }
684     *isEqual = (memcmp(peerPseudonymIdBuff->val, computePeerPseudonymId, PSEUDONYM_ID_LEN) == 0);
685     return HC_SUCCESS;
686 }
687 
GetPeerChallenge(const CJson * payload,Uint8Buff * peerPseudonymChallengeBuff,PakeParams * params)688 static int32_t GetPeerChallenge(const CJson *payload, Uint8Buff *peerPseudonymChallengeBuff, PakeParams *params)
689 {
690     uint8_t peerChallenge[PSEUDONYM_COMBINE_CHALLENGE_LEN] = { 0 };
691     if (GetByteFromJson(payload, FIELD_PSEUDONYM_CHALLENGE, peerChallenge,
692         PSEUDONYM_COMBINE_CHALLENGE_LEN) != HC_SUCCESS) {
693         LOGE("Failed to get peer challenge!");
694         return HC_ERR_JSON_GET;
695     }
696     if (memcpy_s(peerPseudonymChallengeBuff->val, PSEUDONYM_CHALLENGE_LEN, peerChallenge,
697         PSEUDONYM_CHALLENGE_LEN) != EOK) {
698         LOGE("Failed to copy peer pseudonym challenge!");
699         return HC_ERR_MEMORY_COPY;
700     }
701     if (memcpy_s(params->peerNextPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN,
702         peerChallenge + PSEUDONYM_CHALLENGE_LEN, PSEUDONYM_CHALLENGE_LEN) != EOK) {
703         LOGE("Failed to copy peer next pseudonym challenge!");
704         return HC_ERR_MEMORY_COPY;
705     }
706     return HC_SUCCESS;
707 }
708 
CheckPseudonymId(PakeParams * params,const CJson * in)709 int32_t CheckPseudonymId(PakeParams *params, const CJson *in)
710 {
711     if (params == NULL || in == NULL) {
712         LOGE("Invalid params!");
713         return HC_ERR_INVALID_PARAMS;
714     }
715     const CJson *payload = GetObjFromJson(in, FIELD_PAYLOAD);
716     if (payload == NULL) {
717         LOGE("Failed to get payload!");
718         return HC_ERR_JSON_GET;
719     }
720     uint8_t peerPseudonymId[PSEUDONYM_ID_LEN] = { 0 };
721     if (GetByteFromJson(payload, FIELD_P2P_PSEUDONYM_ID, peerPseudonymId, PSEUDONYM_ID_LEN) != HC_SUCCESS) {
722         LOGE("Failed to get peer pseudonym id!");
723         return HC_ERR_JSON_GET;
724     }
725     uint8_t peerPseudonymChallenge[PSEUDONYM_CHALLENGE_LEN] = { 0 };
726     Uint8Buff peerPseudonymChallengeBuff = { peerPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
727     int32_t res = GetPeerChallenge(payload, &peerPseudonymChallengeBuff, params);
728     if (res != HC_SUCCESS) {
729         return res;
730     }
731     bool isEqual = false;
732     if (params->pseudonymExtInfo.peerNextPseudonymId.val != NULL) {
733         isEqual = (memcmp(peerPseudonymId, params->pseudonymExtInfo.peerNextPseudonymId.val, PSEUDONYM_ID_LEN) == 0);
734     }
735     if (!isEqual) {
736         Uint8Buff peerPseudonymIdBuff = { peerPseudonymId, PSEUDONYM_ID_LEN };
737         res = CheckPseudonymIdByCompute(params, &peerPseudonymChallengeBuff, &peerPseudonymIdBuff, &isEqual);
738         if (res != HC_SUCCESS) {
739             LOGE("Failed to check pseudonym id by compute!");
740             return res;
741         }
742     }
743     if (!isEqual) {
744         LOGE("Check pseudonym id failed!");
745         return HC_ERR_MEMORY_COMPARE;
746     }
747     LOGI("Check pseudonym id succeed.");
748     return HC_SUCCESS;
749 }
750 
GeneratePseudonymPskExtInfo(const PakeParams * params,const Uint8Buff * selfNextPseudonymIdBuff,const Uint8Buff * peerNextPseudonymIdBuff,Uint8Buff * extInfoBuff)751 static int32_t GeneratePseudonymPskExtInfo(const PakeParams *params, const Uint8Buff *selfNextPseudonymIdBuff,
752     const Uint8Buff *peerNextPseudonymIdBuff, Uint8Buff *extInfoBuff)
753 {
754     CJson *extInfoJson = CreateJson();
755     if (extInfoJson == NULL) {
756         LOGE("Failed to create extInfo json!");
757         return HC_ERR_JSON_CREATE;
758     }
759     if (AddByteToJson(extInfoJson, FIELD_SELF_NEXT_PSEUDONYM_ID, selfNextPseudonymIdBuff->val,
760         PSEUDONYM_ID_LEN) != HC_SUCCESS) {
761         LOGE("Failed to add self next pseudonym id!");
762         FreeJson(extInfoJson);
763         return HC_ERR_JSON_ADD;
764     }
765     if (AddByteToJson(extInfoJson, FIELD_SELF_NEXT_PSEUDONYM_CHALLENGE, params->selfNextPseudonymChallenge,
766         PSEUDONYM_CHALLENGE_LEN) != HC_SUCCESS) {
767         LOGE("Failed to add self next pseudonym challenge!");
768         FreeJson(extInfoJson);
769         return HC_ERR_JSON_ADD;
770     }
771     if (AddByteToJson(extInfoJson, FIELD_PEER_NEXT_PSEUDONYM_ID, peerNextPseudonymIdBuff->val,
772         PSEUDONYM_ID_LEN) != HC_SUCCESS) {
773         LOGE("Failed to add peer next pseudonym id!");
774         FreeJson(extInfoJson);
775         return HC_ERR_JSON_ADD;
776     }
777     char *extInfoJsonStr = PackJsonToString(extInfoJson);
778     FreeJson(extInfoJson);
779     if (extInfoJsonStr == NULL) {
780         LOGE("Failed to pack extInfo json to string!");
781         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
782     }
783     extInfoBuff->val = (uint8_t *)extInfoJsonStr;
784     extInfoBuff->length = HcStrlen(extInfoJsonStr) + 1;
785     return HC_SUCCESS;
786 }
787 
SaveExtInfoToPseudonymPsk(const PakeParams * params,const Uint8Buff * extInfoStrBuff,const Uint8Buff * pskAliasBuff)788 static int32_t SaveExtInfoToPseudonymPsk(const PakeParams *params, const Uint8Buff *extInfoStrBuff,
789     const Uint8Buff *pskAliasBuff)
790 {
791     uint8_t baseKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
792     Uint8Buff baseKeyAlias = { baseKeyAliasVal, PAKE_KEY_ALIAS_LEN };
793     Uint8Buff pkgNameBuff = { (uint8_t *)params->packageName, HcStrlen(params->packageName)};
794     Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
795     int32_t res = GenerateKeyAlias(&pkgNameBuff, &serviceTypeBuff, KEY_ALIAS_PSK, &params->baseParams.idPeer,
796         &baseKeyAlias);
797     if (res != HC_SUCCESS) {
798         LOGE("Failed to generate psk alias!");
799         return res;
800     }
801     res = ToLowerCase(&baseKeyAlias);
802     if (res != HC_SUCCESS) {
803         LOGE("Failed to convert psk alias to lower case!");
804         return res;
805     }
806     uint8_t outKeyVal[PAKE_PSK_LEN] = { 0 };
807     Uint8Buff outKeyBuff = { outKeyVal, PAKE_PSK_LEN };
808     KeyParams keyParams = { { baseKeyAlias.val, baseKeyAlias.length, true }, true, params->baseParams.osAccountId };
809     res = params->baseParams.loader->computePseudonymPsk(&keyParams, pskAliasBuff, extInfoStrBuff,
810         &outKeyBuff);
811     if (res != HC_SUCCESS) {
812         LOGE("Failed to save extInfo to pseudonym psk!");
813     }
814     return res;
815 }
816 
SaveNextPseudonymIdAndChallenge(PakeParams * params)817 int32_t SaveNextPseudonymIdAndChallenge(PakeParams *params)
818 {
819     int32_t res = GeneratePseudonymPskIfNotExist(params);
820     if (res != HC_SUCCESS) {
821         return res;
822     }
823     Uint8Buff serviceTypeBuff = { (uint8_t *)params->serviceType, HcStrlen(params->serviceType) };
824     uint8_t pskAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
825     Uint8Buff pskAlias = { pskAliasVal, PAKE_KEY_ALIAS_LEN };
826     res = GeneratePseudonymPskAlias(&serviceTypeBuff, &(params->baseParams.idPeer), &pskAlias);
827     if (res != HC_SUCCESS) {
828         LOGE("Failed to generate pseudonym psk alias!");
829         return res;
830     }
831     res = ToLowerCase(&pskAlias);
832     if (res != HC_SUCCESS) {
833         LOGE("Failed to convert pseudonym psk alias to lower case!");
834         return res;
835     }
836     uint8_t selfNextPseudonymId[PSEUDONYM_ID_LEN] = { 0 };
837     Uint8Buff selfNextPseudonymIdBuff = { selfNextPseudonymId, PSEUDONYM_ID_LEN };
838     Uint8Buff selfNextPseudonymChallengeBuff = { params->selfNextPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
839     KeyParams pskAliasParams = { { pskAlias.val, pskAlias.length, true }, true, params->baseParams.osAccountId };
840     res = params->baseParams.loader->computeHmacWithThreeStage(&pskAliasParams, &selfNextPseudonymChallengeBuff,
841         &selfNextPseudonymIdBuff);
842     if (res != HC_SUCCESS) {
843         LOGE("Failed to compute next self pseudonym id!");
844         return res;
845     }
846     uint8_t peerNextPseudonymId[PSEUDONYM_ID_LEN] = { 0 };
847     Uint8Buff peerNextPseudonymIdBuff = { peerNextPseudonymId, PSEUDONYM_ID_LEN };
848     Uint8Buff peerNextPseudonymChallengeBuff = { params->peerNextPseudonymChallenge, PSEUDONYM_CHALLENGE_LEN };
849     res = params->baseParams.loader->computeHmacWithThreeStage(&pskAliasParams, &peerNextPseudonymChallengeBuff,
850         &peerNextPseudonymIdBuff);
851     if (res != HC_SUCCESS) {
852         LOGE("Failed to compute next peer pseudonym id!");
853         return res;
854     }
855     Uint8Buff extInfoStrBuff = { NULL, 0 };
856     res = GeneratePseudonymPskExtInfo(params, &selfNextPseudonymIdBuff, &peerNextPseudonymIdBuff, &extInfoStrBuff);
857     if (res != HC_SUCCESS) {
858         return res;
859     }
860     res = SaveExtInfoToPseudonymPsk(params, &extInfoStrBuff, &pskAlias);
861     FreeJsonString((char *)extInfoStrBuff.val);
862     return res;
863 }