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(¶ms->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, ¶ms->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, ¶ms->isSelfFromUpgrade);
208 (void)GetBoolFromJson(in, FIELD_IS_PEER_FROM_UPGRADE, ¶ms->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(¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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 }