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(¶ms->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, ¶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: %" 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, ¶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: %" 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(¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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 }